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 ...
随机推荐
- 移动web基本知识
1.pixel像素基础 1.px:csspixel 逻辑像素,浏览器所使用的抽象单位 2.dp,pt:设备无关像素 3.devicePixelPatio 设备像素缩放比例 2.viewport 1. ...
- 阿里签名中URLEncode于C#URLEncod不同之处
问题 如上图所示,阿里云的PercentEncode 转换! 为 %21 PercentEncode 源码为: package com.aliyuncs.auth; import java.io.Un ...
- Windows 常用运行库下载 (DirectX、VC++、.Net Framework等)
经常听到有朋友抱怨他的电脑运行软件或者游戏时提示缺少什么 d3dx9_xx.dll 或 msvcp71.dll.msvcr71.dll又或者是 .Net Framework 初始化之类的错误而无法正常 ...
- 原生javascript 固定表头原理与源码
我在工作中需要固定表头这个功能,我不想去找,没意思.于是就写了一个,我写的是angularjs 自定义指令 起了个 "fix-header" ,有人叫 "freeze- ...
- Asp.Net WebApi核心对象解析(上篇)
生活需要自己慢慢去体验和思考,对于知识也是如此.匆匆忙忙的生活,让人不知道自己一天到晚都在干些什么,似乎每天都在忙,但又好似不知道自己到底在忙些什么.不过也无所谓,只要我们知道最后想要什么就行.不管怎 ...
- Mybatis XML配置
Mybatis常用带有禁用缓存的XML配置 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE ...
- FFmpeg 中AVPacket的使用
AVPacket保存的是解码前的数据,也就是压缩后的数据.该结构本身不直接包含数据,其有一个指向数据域的指针,FFmpeg中很多的数据结构都使用这种方法来管理数据. AVPacket的使用通常离不开下 ...
- CentOS7使用firewalld打开关闭防火墙与端口(转载)
1.firewalld的基本使用 启动: systemctl start firewalld 查看状态: systemctl status firewalld 停止: systemctl disabl ...
- MATLAB中绘制质点轨迹动图并保存成GIF
工作需要在MATLAB中绘制质点轨迹并保存成GIF以便展示. 绘制质点轨迹动图可用comet和comet3命令,使用例子如下: t = 0:.01:2*pi;x = cos(2*t).*(cos(t) ...
- ComponentPattern (组合模式)
import java.util.LinkedList; /** * 组合模式 * * @author TMAC-J 主要用于树状结构,用于部分和整体区别无区别的场景 想象一下,假设有一批连锁的理发店 ...