CoordinatorLayout,AppBarLayout中Edittext被键盘覆盖问题解决
作者:互联网
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="visible">
<Edittext/>
</androidx.appcompat.widget.LinearLayoutCompat>
</com.google.android.material.appbar.AppBarLayout>
</com.google.android.material.appbar.CollapsingToolbarLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
以上就是Edittext所处的位置。
我上外网翻了了一遍,发现google其实是不建议CollapsingToolbarLayout中使用Edittext,因为它对 adjustResize 是无效的,并且短时间内不会解决。
所以只能自己手动解决。
步骤思路:
1.获取Edittext在屏幕中的位置
2.获取键盘弹出高度
3.计算需要滑动的高度
4.监听触碰edittext被触碰,然后滑动AppBarLayout
首先,获取edittext 在屏幕中的位置:
val location = IntArray(2)
edittext.getLocationOnScreen(location)
//location[1] 即位置
接着获取键盘高度:
private var softKeyboardHeight = 0
private var keyboardOpen = false
private val mGlobalLayoutListener = OnGlobalLayoutListener {
val r = Rect()
//获取当前窗口实际的可见区域
window.decorView.getWindowVisibleDisplayFrame(r)
val height: Int = r.height()
if (mWindowHeight == 0) {
//一般情况下,这是原始的窗口高度
mWindowHeight = height
} else {
if (mWindowHeight != height) {
//两次窗口高度相减,就是软键盘高度
softKeyboardHeight = mWindowHeight - height
keyboardOpen = true
}
}
}
//onCreate的时候注册监听
window.decorView.viewTreeObserver.addOnGlobalLayoutListener(mGlobalLayoutListener)
//记得销毁
override fun onDestroy() {
super.onDestroy()
window.decorView.viewTreeObserver.removeOnGlobalLayoutListener(mGlobalLayoutListener)
}
计算上滑动高度:
val limit = ScreenUtil.getDisplayHeight() - softKeyboardHeight.toFloat() //键盘弹窗位置
val current = location[1] + ScreenUtil.dip2px(40f) - ScreenUtil.getStatusBarHeight(this) //输入框底部位置,40f 是输入框高度,getStatusBarHeight 状态栏高度
val distance = current - limit; //要滑动高度
监听,滑动:
val touchListener = object : View.OnTouchListener {
override fun onTouch(v: View?, event: MotionEvent?): Boolean {
scrollAppBar()
return false
}
}
edittext.setOnTouchListener(touchListener)
fun scrollAppBar(){
if (keyboardOpen) {
val layoutParams: ViewGroup.LayoutParams = appbarLayout.getLayoutParams()
val behavior = (layoutParams as CoordinatorLayout.LayoutParams).behavior
if (behavior is AppBarLayout.Behavior) {
if (distance > 0) {
behavior.topAndBottomOffset = (appBarScrollHeight - distance).toInt()
}
}
keyboardOpen = false
}
}
搞定。
代码是从项目中抽象出来的,实际业务逻辑复杂的多,核心代码已经在上面了,大家举一反三吧。
补充下:
appBarScrollHeight 是,AppBarLayout 当前的滚动位置。这个是需要实时记录的,以下是代码。
var appBarScrollHeight = 0
appbarLayout.addOnOffsetChangedListener(object : AppBarLayout.OnOffsetChangedListener {
override fun onOffsetChanged(appBarLayout: AppBarLayout?, verticalOffset: Int) {
appBarScrollHeight = verticalOffset
}
})
标签:AppBarLayout,val,Edittext,高度,height,location,edittext,CoordinatorLayout 来源: https://blog.csdn.net/u013597998/article/details/118764584