使用微信的朋友圈会发现,点击某一条评论后输入框会弹出来,然后所点击的那一项会自动地滚动到输入框上方的位置,这样如果开始所点击的评论在屏幕很下方的话,就不会被输入框遮住,虽然微信这一点在我的MX2频繁点几次后滚动的位置就完全错误了,但据说在有些机型上效果还不错,还有其他地方可能会有类似的需求,比如登录时软键盘可能会把登录按钮遮住。

要实现这个功能需要注意的地方主要有两点:

  1. 什么时候进行滚动操作,以及有可能还需要在输入框消失时回滚回去。
  2. 输入框弹出后所点击的项要滚动到输入框上方,这就需要我们计算要滚动的距离。

针对第一点,评论框出现在软键盘的上方,一般情况下软键盘出来后评论框的位置会移动,也就是会出现Layout操作,所以可以在Layout时计算滚动距离,时机就是:

view.getViewTreeObserver().addOnGlobalLayoutListener

评论框Layout时的回调,在这里计算需要滚动的距离。

接下来就是滚动距离的计算。

滚动距离=所点击的项底部的Y坐标 - 软键盘弹出后输入框顶部的Y坐标

所以只要知道这两个坐标就可以知道需要滚动的距离,获得坐标以很简单,通过getGlobalVisibleRect就可以了,当然还有其他方法,但由于是计算的差值,保证两次计算坐标时用同一个就可以了。获得坐标后直接smoothScrollBy。

原理就是这么简单,不过要实现起来,细节问题搞得人恶心。

比如说输入框初始的可见性可能是GONE,也可能是Visible,如果是GONE,那么软键盘弹出时可能会有两个过程,1.从GONE到Visible会layout一次,2.软键盘弹出又layout一次,隐藏时一样。界面刚显示时也会layout,所以这就需要判断在onGlobalLayout时是否需要过滤事件。

在MX2上实验,smoothScrollBy有两个参数,第二个是duration,如果duration过小,可能你传入的distance是600,系统却可能只会滚动500。

有时可能也需要在输入框的onFocusChange中滚动。

如果到了列表底部,计算出的距离可能和实际滚动的距离也不一样,这种情况也可以用setSelectionFromTop的方法让所点击的Item在屏幕最上方,当然也可以再计算偏移,总之异常繁琐。

如果是像登录这种情况,UI简单的,要加个ScrollView,也比较好处理,软键盘弹出时直接滚动到底部,隐藏时滚动到顶部。

总之,要实现自动滚动,首先就要有一个控件随着软键盘的弹出消失而移动位置,软键盘弹出后出现在软键盘的上方,哪怕它看不见只是作为一个anchor。

其次,需要计算滚动距离,看情况有所不同,也是最麻烦的,可能需要知道输入框的状态是隐藏,显示在屏幕底部而软键盘没出来,还是软键盘出来了。不过在输入框初始隐藏在布局最下方的情况下,这三种情况输入框的坐标也只有3个值,也可以根据这个值判断输入框的状态,当然不排除有些输入法可以调整软键盘高度而用户又很配合地在输入时调整。

反正如果有这需求就恶心死吧。在项目三个地方实现,大致方法都是一样的,细节都有差异。

Android点击列表后弹出输入框,所点击项自动滚动到输入框上方的更多相关文章

  1. JS 点击按钮后弹出遮罩层,有关闭按钮

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <t ...

  2. JQuery弹出层,点击按钮后弹出遮罩层,有关闭按钮

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <t ...

  3. JQuery弹出层,点击按钮后弹出遮罩层,有关闭按钮【转】

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <t ...

  4. 我的Android进阶之旅------>Android的ListView数据更新后,如何使最新的条目可以自动滚动到可视范围内?

    在ListView的layout配置中添加 android:transcriptMode="alwaysScroll" <ListView android:id=" ...

  5. js实现点击<li>标签弹出其索引值

    据说这是一道笔试题,以下是代码,没什么要文字叙述的,就是点击哪个<li>弹出哪个<li>的索引值即可: <html> <head> <style& ...

  6. 手机调用系统的拍照和裁剪功能,假设界面有输入框EditText,在一些手机会出现点击EditText会弹出输入法,却不能输入的情况。

    1. 拍照裁剪后 点击EditText会弹出输入法,却不能输入.可是点击点一EdtiText就能够输入了,所以我就写了一个看不见的EdtiText,切换焦点,这样就攻克了这个奇怪的这问题,应该是and ...

  7. SVN 安装后右键出现点击鼠标右键弹出错误提示:CrashHandler initialization error

    SVN 安装后右键出现点击鼠标右键弹出错误提示:CrashHandler initialization error 原因是目标文件夹中缺少SendRpt.exe文件 解决方案:找svn是好的的同事将b ...

  8. vue封装公用弹出框方法,实现点击出现操作弹出框

    vue封装公用弹出框方法,实现点击出现操作弹出框 如上图所示,这次要实现一个点击出现操作弹框的效果:并将这个功能封装成一个函数,便于在项目的多个地方使用. 具体思路是: 封装一个组件,组件保护一个插槽 ...

  9. android PopupWindow实现从底部弹出或滑出选择菜单或窗口

    本实例弹出窗口主要是继承PopupWindow类来实现的弹出窗体,布局可以根据自己定义设计.弹出效果主要使用了translate和alpha样式实现,具体实习如下: 第一步:设计弹出窗口xml: &l ...

随机推荐

  1. 关于Unity3D自定义编辑器的学习

    被人物编辑器折腾了一个月,最终还是交了点成品上去(还要很多优化都还么做).  刚接手这项工作时觉得没概念,没想法,不知道.后来就去看<<Unity5.X从入门到精通>>中有关于 ...

  2. MySQL高级知识- MySQL的架构介绍

    [TOC] 1.MySQL 简介 概述 MySQL是一个关系型数据库管理系统,由瑞典MySQL AB公司开发,目前属于Oracle公司. MySQL是一种关联数据库管理系统,将数据保存在不同的表中,而 ...

  3. Hibernatel框架关联映射

    Hibernatel框架关联映射 Hibernate程序执行流程: 1.集合映射 需求:网络购物时,用户购买商品,填写地址 每个用户会有不确定的地址数目,或者只有一个或者有很多.这个时候不能把每条地址 ...

  4. 使用C#处理基于比特流的数据

    使用C#处理基于比特流的数据 0x00 起因 最近需要处理一些基于比特流的数据,计算机处理数据一般都是以byte(8bit)为单位的,使用BinaryReader读取的数据也是如此,即使读取bool型 ...

  5. 领域驱动和MVVM应用于UWP开发的一些思考

    领域驱动和MVVM应用于UWP开发的一些思考 0x00 起因 有段时间没写博客了,其实最近本来是根据梳理的MSDN上的资料(UWP开发目录整理)有条不紊的进行UWP学习的.学习中有了心得体会或遇到了问 ...

  6. 在docker中运行ASP.NET Core Web API应用程序(附AWS Windows Server 2016 widt Container实战案例)

    环境准备 1.亚马逊EC2 Windows Server 2016 with Container 2.Visual Studio 2015 Enterprise(Profresianal要装Updat ...

  7. CRL快速开发框架系列教程五(使用缓存)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

  8. [EasyUI美化换肤]更换EasyUi图标

    前言 本篇文章主要是记录一些换EasyUI皮肤的过程,备忘.也欢迎美工大神各路UI给点好意见,EasyUI我就不介绍了,自行百度吧..(So..所以别问我是不是响应式..本身EasyUI就不是响应式. ...

  9. ASP.NET中画图形验证码

    context.Response.ContentType = "image/jpeg"; //生成随机的中文验证码 string yzm = "人口手大小多少上中下男女天 ...

  10. Java开发中的23种设计模式详解

    [放弃了原文访问者模式的Demo,自己写了一个新使用场景的Demo,加上了自己的理解] [源码地址:https://github.com/leon66666/DesignPattern] 一.设计模式 ...