仿豆瓣发布-编辑框自适应高度,自动滚动定位到焦点输入
效果图
随着输入的文本自动增加高度,键盘上方自定义菜单布局,随键盘弹起
点击编辑框,自动滚动到焦点处输入
布局层次
<ConstraintLayout>
<ScrollView>
<LinearLayout>
<Edittext/>
<自定义布局/>
</LinearLayout>
</ScrollView>
<键盘上方自定义布局/>
</ConstraintLayout>
想要实现自动焦点定位,需要手动计算滚动距离,系统也有自带的滚动效果,不过因为这里有自定义布局,所以不兼容
系统原生自带了键盘弹起顶起布局的方式,并且点击 edittext 后 scrollView 里的 edittext 会自动滚动定位到焦点区域
有它的便捷也有它的问题,比如自定义键盘上方的布局后,定位不准确,因为自定义的布局不属于键盘,系统不会计算在内,而且自动定位部分手机不起效果,需要做兼容
滚动后内容区域不在键盘上方自定义布局上,而是滚动到键盘上方,缺少了自定义布局的那段高度
滚动方法很简单,直接调用 scrollView.smoothScrollTo(0, scrollTo) 方法就行
然后需要提前测量好键盘上方布局的高度跟键盘弹起的高度
键盘直接使用 Blankj 工具类 KeyboardUtils 监听,布局高度直接测量就行
接下来监听键盘弹起状态 onSoftInputChanged,每次弹起键盘手动给 scrollView 设置 bottomMargin,为了让布局在键盘弹起时在键盘上方位置,如果有自定义布局需要把布局高度也计算上
到这里键盘弹起结束,接下来进入核心,自动滚动定位焦点
首先是获取到当前焦点的精确坐标,有了坐标才能跳转
一开始我尝试了 touch 触摸事件,通过点击的位置来获取坐标,计算滑动距离,不过这个方案很快被推翻
因为不是很准确,加上内容是自适应高度,滑动距离过长时问题多
后来发现可以通过 getLineForOffset 方法获取编辑框当前的行数,然后在通过 getLineBounds 方法获取行坐标
获取坐标后需要计算出 scrollView 滑动的距离
滑动距离 = 当前坐标 - 键盘弹起高度 + 自定义布局高度
如果没有自定义布局就不用算
private fun scrollEdit() { //当前光标的坐标-键盘高度 val scrollTo = getCurrentEditY() - boardHeight + menuHeight mBinding.scrollView.post { //计算实际滚动的位置 mBinding.scrollView.smoothScrollTo(0, scrollTo) } }
得到滚动距离后直接在 onTextChanged 监听里去调用上面的方法就行了,此时只要文本更改就会重新定位,自动滚动到你输入的内容区域上
注意点
1、焦点自动定位问题
如果存在 ScrollView 嵌套 Edittext,那么会有部分手机系统会自动滚动到焦点位置的情况,但是这不符合我们的自定义需求,毕竟系统定位的不准确,没有导航栏适配,
滚动的位置会出现遮挡键盘上方布局的情况,所以需要重写方法去限制一下
2、导航栏适配问题
因为底部有自定义布局,会跟随键盘弹起,所以需要适配系统导航栏,否则底部自定义布局不好适配
3、自动滚动问题
核心就在于滚动定位,需要自己计算滚动距离,并且在输入的时候自动定位到该区域
并且如果调用滚动方法时,需要在变动之后调用,否则会跟系统测量结果有冲突,也就是在点击后调用 post 方法,在里面做滚动操作
相关文章
- 【技术种草】cdn+轻量服务器+hugo=让博客“云原生”一下
- CLB运维&运营最佳实践 ---访问日志大洞察
- vnc方式登陆服务器
- 轻松学排序算法:眼睛直观感受几种常用排序算法
- 十二个经典的大数据项目
- 为什么使用 CDN 内容分发网络?
- 大数据——大数据默认端口号列表
- Weld 1.1.5.Final,JSR-299 的框架
- JavaFX 2012:彻底开源
- 提升as3程序性能的十大要点
- 通过凸面几何学进行独立于边际的在线多类学习
- 利用行动影响的规律性和部分已知的模型进行离线强化学习
- ModelLight:基于模型的交通信号控制的元强化学习
- 浅谈Visual Source Safe项目分支
- 基于先验知识的递归卡尔曼滤波的代理人联合状态和输入估计
- 结合网络结构和非线性恢复来提高声誉评估的性能
- 最佳实践丨云开发CloudBase多环境管理实践
- TimeVAE:用于生成多变量时间序列的变异自动编码器
- 具有线性阈值激活的神经网络:结构和算法
- 内网渗透之横向移动 -- 从域外向域内进行密码喷洒攻击