Android点击列表后弹出输入框,所点击项自动滚动到输入框上方
使用微信的朋友圈会发现,点击某一条评论后输入框会弹出来,然后所点击的那一项会自动地滚动到输入框上方的位置,这样如果开始所点击的评论在屏幕很下方的话,就不会被输入框遮住,虽然微信这一点在我的MX2频繁点几次后滚动的位置就完全错误了,但据说在有些机型上效果还不错,还有其他地方可能会有类似的需求,比如登录时软键盘可能会把登录按钮遮住。
要实现这个功能需要注意的地方主要有两点:
- 什么时候进行滚动操作,以及有可能还需要在输入框消失时回滚回去。
- 输入框弹出后所点击的项要滚动到输入框上方,这就需要我们计算要滚动的距离。
针对第一点,评论框出现在软键盘的上方,一般情况下软键盘出来后评论框的位置会移动,也就是会出现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点击列表后弹出输入框,所点击项自动滚动到输入框上方的更多相关文章
- JS 点击按钮后弹出遮罩层,有关闭按钮
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <t ...
- JQuery弹出层,点击按钮后弹出遮罩层,有关闭按钮
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <t ...
- JQuery弹出层,点击按钮后弹出遮罩层,有关闭按钮【转】
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <t ...
- 我的Android进阶之旅------>Android的ListView数据更新后,如何使最新的条目可以自动滚动到可视范围内?
在ListView的layout配置中添加 android:transcriptMode="alwaysScroll" <ListView android:id=" ...
- js实现点击<li>标签弹出其索引值
据说这是一道笔试题,以下是代码,没什么要文字叙述的,就是点击哪个<li>弹出哪个<li>的索引值即可: <html> <head> <style& ...
- 手机调用系统的拍照和裁剪功能,假设界面有输入框EditText,在一些手机会出现点击EditText会弹出输入法,却不能输入的情况。
1. 拍照裁剪后 点击EditText会弹出输入法,却不能输入.可是点击点一EdtiText就能够输入了,所以我就写了一个看不见的EdtiText,切换焦点,这样就攻克了这个奇怪的这问题,应该是and ...
- SVN 安装后右键出现点击鼠标右键弹出错误提示:CrashHandler initialization error
SVN 安装后右键出现点击鼠标右键弹出错误提示:CrashHandler initialization error 原因是目标文件夹中缺少SendRpt.exe文件 解决方案:找svn是好的的同事将b ...
- vue封装公用弹出框方法,实现点击出现操作弹出框
vue封装公用弹出框方法,实现点击出现操作弹出框 如上图所示,这次要实现一个点击出现操作弹框的效果:并将这个功能封装成一个函数,便于在项目的多个地方使用. 具体思路是: 封装一个组件,组件保护一个插槽 ...
- android PopupWindow实现从底部弹出或滑出选择菜单或窗口
本实例弹出窗口主要是继承PopupWindow类来实现的弹出窗体,布局可以根据自己定义设计.弹出效果主要使用了translate和alpha样式实现,具体实习如下: 第一步:设计弹出窗口xml: &l ...
随机推荐
- 【AR实验室】ARToolKit之Example篇
0x00 - 前言 PS : 我突然意识到ARToolKit本质可能就是一个可以实时求解相机内外参的解决方案. 拿到一个新的SDK,90%的人应该都会先跑一下Example.拿到ARToolKit的S ...
- SQL Server2014 SP2新增的数据库克隆功能
SQL Server2014 SP2新增的数据库克隆功能 创建测试库 --创建测试数据库 create database testtest use testtest go --创建表 )) --插入数 ...
- 《你不知道的JavaScript》整理(四)——原型
一.[[Prototype]] JavaScript中的对象有一个特殊的[[Prototype]]内置属性,其实就是对于其他对象的引用. var myObject = { a: 2 }; myObje ...
- 玩转spring boot——结合AngularJs和JDBC
参考官方例子:http://spring.io/guides/gs/relational-data-access/ 一.项目准备 在建立mysql数据库后新建表“t_order” ; -- ----- ...
- java单向加密算法小结(1)--Base64算法
从这一篇起整理一下常见的加密算法以及在java中使用的demo,首先从最简单的开始. 简单了解 Base64严格来说并不是一种加密算法,而是一种编码/解码的实现方式. 我们都知道,数据在计算机网络之间 ...
- 【置顶】CoreCLR系列随笔
CoreCLR配置系列 在Windows上编译和调试CoreCLR GC探索系列 C++随笔:.NET CoreCLR之GC探索(1) C++随笔:.NET CoreCLR之GC探索(2) C++随笔 ...
- [原] KVM 虚拟化原理探究(2)— QEMU启动过程
KVM 虚拟化原理探究- QEMU启动过程 标签(空格分隔): KVM [TOC] 虚拟机启动过程 第一步,获取到kvm句柄 kvmfd = open("/dev/kvm", O_ ...
- JAVA FreeMarker工具类
FreeMarkerUtil.java package pers.kangxu.datautils.utils; import java.io.File; import java.io.StringW ...
- Python学习基础
1.使用范围: 大数据 .图像处理.web .运维.爬虫.自动化.科学计算 2.准备环境: linux/mac python 3.5.2 ipython vim/sublime/atom 3.列表 3 ...
- Jenkins的一个bug-同时build一个项目两次导致失败
我们有一个job A, A只是配置了一些参数,它会去触发模板job B. 我一开始点击构建A, 马上发现参数配置不对,于是撤消了构建,但是我没有发现B已经被触发,我重新配置参数,然后再次构建A,这个时 ...