Android 全屏模式下输入框被遮挡问题处理
前些天,在做一个页面表单输入需求时,由于我们项目添加了全屏沉浸式状态栏,所以遇到了键盘挡住输入框的问题,简单处理了一下,又发现即使做到键盘不遮挡输入框,又会把页面顶上去,看起来及其不美观。
具体情况如下:
情况一:键盘挡住输入框
情况二:页面整体被顶上去
添加代码如下:
<activity
android:name=".activity.AddGoldActivity"
android:windowSoftInputMode="adjustPan|stateHidden" />
下面是解决方案
先来看一下实现后的效果:
解决思路:监测到键盘弹起时,重新绘制页面
-
导入:InputHandleUtil 工具类,之前导入 ZyFrame 框架的小伙伴,可以直接调用
框架地址:https://github.com/Sunnyfor/ZyFrame 点击查看
在线依赖:implementation ‘com.github.Sunnyfor:ZyFrame:1.4.3’
-
调用:InputHandleUtil().handleInputView(rootView, scrollView, ignoreView)
扫描二维码关注公众号,回复: 12760829 查看本文章参数说明:
(1)rootView:必传参数,系统的根布局view (android.R.id.content)
(2)scrollView:非必传,包含 EditText 的 ScrollView
(3)ignoreView:非必传,想要忽略的View,键盘弹出时,不显示此 view,例如:底部提交按钮
注:后两个参数是配合使用的
效果一:
InputHandleUtil().handleInputView(rootView)
效果二:
InputHandleUtil().handleInputView(rootView, scrollView, ignoreView)
效果三:对于底部是输入框的情况也同样适用
工具类代码如下:
/**
* Desc 用于处理全屏模式下输入框被遮挡问题
* Author ZY
* Date 2021/3/16
*/
class InputHandleUtil {
private var mRootView: ViewGroup? = null
private var rootViewParams: FrameLayout.LayoutParams? = null
private var rootViewMargin = 0
private var lastRootLayoutHeight = 0
private var scrollViewParams: ViewGroup.MarginLayoutParams? = null
private var scrollViewMargin = 0
private var ignoreViewParams: ViewGroup.MarginLayoutParams? = null
/**
* 处理包含输入框的容器方法
* @param rootView 基本View
* @param scrollView 只处理ScrollView内部view
* @param ignoreView 忽略scrollView外部的View
*/
fun handleInputView(
rootView: ViewGroup,
scrollView: ScrollView? = null,
ignoreView: View? = null
) {
mRootView = rootView.getChildAt(0) as ViewGroup
rootViewParams = mRootView?.layoutParams as FrameLayout.LayoutParams
rootViewMargin = rootViewParams?.bottomMargin ?: 0
mRootView?.viewTreeObserver?.addOnGlobalLayoutListener {
resizeLayout(scrollView, ignoreView)
}
lastRootLayoutHeight = getRootLayoutHeight()
scrollView?.let {
scrollViewParams = it.layoutParams as ViewGroup.MarginLayoutParams
scrollViewMargin = scrollViewParams?.bottomMargin ?: 0
}
ignoreView?.let {
ignoreViewParams = it.layoutParams as ViewGroup.MarginLayoutParams
}
}
private fun resizeLayout(scrollView: ScrollView?, ignoreView: View? = null) {
val currentRootLayoutHeight = getRootLayoutHeight()
if (currentRootLayoutHeight != lastRootLayoutHeight) {
val rootLayoutHeight = mRootView?.rootView?.height ?: 0
val keyBoardHeight = rootLayoutHeight - currentRootLayoutHeight
if (keyBoardHeight > rootLayoutHeight / 4) {
if (scrollView != null) {
val height = ignoreView?.height ?: 0
val topMargin = ignoreViewParams?.topMargin ?: 0
val bottomMargin = ignoreViewParams?.bottomMargin ?: 0
scrollViewParams?.bottomMargin =
keyBoardHeight - height - topMargin - bottomMargin
scrollView.requestLayout()
} else {
rootViewParams?.bottomMargin = rootViewMargin + keyBoardHeight
mRootView?.requestLayout()
}
} else {
if (scrollView != null) {
scrollViewParams?.bottomMargin = scrollViewMargin
//重绘scrollView布局
scrollView.requestLayout()
} else {
rootViewParams?.bottomMargin = rootViewMargin
//重绘xml根布局
mRootView?.requestLayout()
}
}
lastRootLayoutHeight = currentRootLayoutHeight
}
}
private fun getRootLayoutHeight(): Int {
val r = Rect()
mRootView?.getWindowVisibleDisplayFrame(r)
return r.bottom
}
}