一、使用 windowSoftInputMode 配置软键盘弹出的规则
关于windowSoftInputMode 详细使用可以阅读下面这篇文章
这里简单描述一下使用,windowSoftInputMode属性配置在AndroidManifest的对应Activity,大概效果是这样
<activity
android:name=".ui.test.Test4Activity"
android:exported="false"
android:windowSoftInputMode="adjustPan"/>
可以看到在填账号框时,输入框下方的视图都被键盘遮挡住,想要继续输入密码需要关闭键盘再重新点击密码框,体验非常不好。想要优化体验就只能自己处理布局。
二、使用ViewTreeObserver去监听布局动态改变布局的尺寸
首要使用ViewTreeObserver.addOnGlobalLayoutListener添加跟布局的变化,再通过getWindowVisibleDisplayFrame()方法来获取根布局的可显示空间,然后计算得出键盘的高度,最后设置布局的bottompadding值。布局和代码如下
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
tools:context=".ui.test.Test3Activity"
android:background="@color/yellow"
tools:ignore="ResourceName">
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical">
<ImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginTop="400dp"
android:src="@mipmap/ic_launcher" />
<EditText
android:layout_width="match_parent"
android:layout_height="@dimen/height_50"
android:layout_marginTop="@dimen/margin_10"
android:hint="请输入账号" />
<EditText
android:layout_width="match_parent"
android:layout_height="@dimen/height_50"
android:layout_marginTop="@dimen/margin_10"
android:hint="请输入密码" />
<Button
android:layout_width="match_parent"
android:layout_height="@dimen/height_50"
android:background="@color/blue"
android:text="登录" />
</LinearLayout>
</ScrollView>
这里最外层布局使用scrollView 是为了在设置linearLayout 的底部padding,软键盘弹出后,还可以上滑,查看上方视图。
binding.root.viewTreeObserver.addOnGlobalLayoutListener {
val rect = Rect()
binding.root.getWindowVisibleDisplayFrame(rect)
// 这里全屏需要加上状态栏高度 ScreenUtils.getStatusBarHeight()
val fullScreenH = rect.height() +ScreenUtils.getStatusBarHeight()
val scrollH = binding.scrollView.height
//键盘的高度
var keyHeight = scrollH - fullScreenH
//动态设置linearLayout bottom padding
binding.linearLayout.setPadding(0,0,0,keyHeight)
val linearH = binding.linearLayout.height
//滑到底部
binding.scrollView.smoothScrollTo(0,linearH)
Log.e("Test","fullScreenH:$fullScreenH keyHeight:$keyHeight linearH:${linearH}")
}
效果图