使用微信的朋友圈会发现,点击某一条评论后输入框会弹出来,然后所点击的那一项会自动地滚动到输入框上方的位置,这样如果开始所点击的评论在屏幕很下方的话,就不会被输入框遮住,虽然微信这一点在我的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. 谈谈一些有趣的CSS题目(三)-- 层叠顺序与堆栈上下文知多少

    开本系列,讨论一些有趣的 CSS 题目,抛开实用性而言,一些题目为了拓宽一下解决问题的思路,此外,涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题中有你感觉 ...

  2. Apache 与 php的环境搭建

    Apache和PHP的版本分别为: httpd-2.4.9-win64-VC11.zip php-5.6.9-Win32-VC11-x64.zip 下载地址: php-5.6.9-Win32-VC11 ...

  3. Base64编码

    Base64编码 写在前面 今天在做一个Android app时遇到了一个问题:Android端采用ASE对称加密的数据在JavaWeb(jre1.8.0_7)后台解密时,居然解密失败了!经过测试后发 ...

  4. 【SSM框架】Spring + Springmvc + Mybatis 基本框架搭建集成教程

    本文将讲解SSM框架的基本搭建集成,并有一个简单demo案例 说明:1.本文暂未使用maven集成,jar包需要手动导入. 2.本文为基础教程,大神切勿见笑. 3.如果对您学习有帮助,欢迎各种转载,注 ...

  5. load和initialize方法

      一.load 方法什么时候调用: 在main方法还没执行的时候 就会 加载所有类,调用所有类的load方法. load方法是线程安全的,它使用了锁,我们应该避免线程阻塞在load方法. 在项目中使 ...

  6. C++中的引用

    一,C++中引用的基础知识 1.引用的基本概念 1.所谓的引用其实就是对变量起“别名”.引用和变量对应得是相同的内存,修改引用的值,变量的值也会改变,和指针类似. 2.引用在定义的时候必须要初始化,初 ...

  7. EventBus实现activity跟fragment交互数据

    最近老是听到技术群里面有人提出需求,activity跟fragment交互数据,或者从一个activity跳转到另外一个activity的fragment,所以我给大家介绍一个开源项目,EventBu ...

  8. 编写高质量代码:改善Java程序的151个建议(第8章:多线程和并发___建议126~128)

    建议126:适时选择不同的线程池来实现 Java的线程池实现从根本上来说只有两个:ThreadPoolExecutor类和ScheduledThreadPoolExecutor类,这两个类还是父子关系 ...

  9. WebSocket - ( 一.概述 )

    说到 WebSocket,不得不提 HTML5,作为近年来Web技术领域最大的改进与变化,包含CSS3.离线与存储.多媒体.连接性( Connectivity )等一系列领域,而即将介绍的 WebSo ...

  10. [原创]java使用JDBC向MySQL数据库批次插入10W条数据测试效率

    使用JDBC连接MySQL数据库进行数据插入的时候,特别是大批量数据连续插入(100000),如何提高效率呢?在JDBC编程接口中Statement 有两个方法特别值得注意:通过使用addBatch( ...