前言
正在开发中的应用登录与注册模块的按钮会被软键盘遮挡,我需要做下处理。
希望实现的效果为这样:
方案一:使用ViewCompat.setWindowInsetsAnimationCallback + translationY 移动布局实现
首先贴一下实现代码
ViewCompat.setWindowInsetsAnimationCallback(root,object : WindowInsetsAnimationCompat.Callback(DISPATCH_MODE_STOP) {
override fun onProgress(
insets: WindowInsetsCompat,
runningAnimations: MutableList<WindowInsetsAnimationCompat>
): WindowInsetsCompat {
val startBottom = root.height - btn.bottom
val endBottom =
insets.getInsets(WindowInsetsCompat.Type.ime()).bottom.toFloat()
root.translationY = if (endBottom >= startBottom) {
startBottom - endBottom
} else {
0F
}
return insets
}
})
接下来解释一下代码
ViewCompat
这个类为Android11新APIWindowInsetsAnimation
可实现效果的向后兼容类
有关WindowInsetsAnimation
类的介绍可查看谷歌官方账号发布的让您的软键盘动起来系列文章
setWindowInsetsAnimationCallback
此方法用于设置软键盘弹出监听。其中参数root
为ViewBinding生成类.root
是页面根布局,callback
则是关键,实现其中的onProgress
方法即可监听软键盘弹出。当软键盘弹出时,该方法将会被多次回调。这时使用其中的insest参数调用getInsets方法即可获取当前软键盘高度。
startBottom
由于我并不希望软键盘弹出多少界面就往上移动多少,而是希望软键盘遮挡我的按钮多少界面往上移动多少。所以我首先得计算我的按钮距离界面底部的距离,使用root.height - btn.bottom
即可得出我的按钮距离界面底部的距离。btn.bottom获取的是什么可参考细说 Android 控件体系中的view.getBottom()。
endBottom
则为当前软键盘高度。
小结
- 该代码和给控件设置点击监听一样,在
onCreate
中调用注册就行了。 - 使用该方案当软键盘弹出时,整体布局在向上移动中会忽然往下闪动一下然后再正常向上移动,推测是我计算btn底部距离时少算了什么。加了个else = 0F就不闪了,由于最后我没有使用该方案,也就没去深究。 如果你想实现的效果是软键盘弹出多少输入框向上移动多少使用该方案则没问题,不会闪动。我试过了,很丝滑。
- 由于我布局移动的距离较短,当键盘弹出时向上移动动画还很丝滑。但当软键盘隐藏时,动画会很快,看上去就像整体布局闪动了一下就回到了原位一样,很难看。所以我最终没选择这个方案。
方案二:使用ViewCompat.setOnApplyWindowInsetsListener + view.animate().setDuration(duration).translationY(value)移动布局实现
依旧先贴一下实现代码
ViewCompat.setOnApplyWindowInsetsListener(mBinding.root) { _, insets ->
val imeBottom = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom
var to = imeBottom - (mBinding.root.height - mBinding.btnRegister.bottom).toFloat()
to = if (it.to > 0) -to else 0F
root.animate().setDuration(300).translationY(to)
insets
}
接下来解释一下代码
setOnApplyWindowInsetsListener
此方法用于设置软键盘弹出监听,但不会在软键盘弹出时多次回调。只会在软键盘显示与隐藏完成回调。
imeBottom
软键盘高度
to
计算出的我希望布局移动的距离,由于Android的坐标系并不是我们通常印象中的XY轴,而是一个倒转的XY轴,具体依然参考细说 Android 控件体系。所以需要将to
也反转一下。同时不处理小于0的数据。
root.animate().setDuration(300).translationY(to)
这段代码将会生成一个可执行动画,时间为300毫秒,移动方式为平滑Y轴移动。
小结
使用该方案动画时间就可以由我们自己控制了,这样当键盘隐藏时就不会出现动画时间过短像闪动一下就回到了原位的问题。
结语
写这篇文的本意是想着谷歌官方号的让您的软键盘动起来系列第二篇适配软键盘弹出,写的有点晦涩搞的我研究了好久。同时谷歌官方号的那篇文章也没有说该怎样适配Android11之前的软键盘。我想着我掉了这么多头发死了这么多脑细胞,大伙就没必要和我一样这么费神了。
引用