【版权申明】非商业目的可自由转载
博文地址:https://blog.csdn.net/ShuSheng0007/article/details/104232176
出自:shusheng007
文章目录
概述
曾几何时,你是否对软键盘的显示与隐藏,软键盘与页面布局的关系傻傻分不清,测试的小姐姐时不时就会过来抱怨,
王二狗:
“你这个键盘怎么把输入框盖住了,你让我怎么输入啊?“
“你这个键盘怎么把标题栏都顶没了?”
“产品要求一进入这个页面键盘就是要主动弹出来的,你这个没有弹啊?”
“产品要求一进入这个页面键盘是隐藏的,点击输入后才弹出,你这个为什么刚进来就弹出了呢?”
…
如果测试要真是个漂亮的小姐姐,倒也是一桩人间美事,说不定还能碰撞出爱情的小火花,那要是王姐,或者李姐之类胖大妈天天找你谈心,你是不是就要疯了?
所以,让我们一起来彻底搞懂android:windowSoftInputMode
吧,把握主动权!
windowSoftInputMode
android:windowSoftInputMode 一般是配置在AndroidManifest.xml中来设置软键盘的行为的,当然也可以通过代码设置,如下所示
<activity android:name=".Activity2" android:windowSoftInputMode="stateUnspecified|adjustUnspecified"/>
android:windowSoftInputMode
的属性值竟然多达10种,真是丧心病狂,但是仔细研究后发现也不是那么不近人情,接下来就让我们秒懂它吧。
其属性分为两类:6个用来控制软键盘的可见状态,4个用来控制软键盘与视图window的布局关系。
软键盘可见性
假设有两个Activity, Activity1 和Activity2
属性值 | 含义 |
---|---|
stateUnspecified | 系统默认行为,如果我们不在AndroidManifest设置windowSfotinputModle的值,默认就使用这个值,如果在App的主题(theme)中设置了属性值,那么系统就会采用主题里的值,否则系统会根据不同的场景决定键盘的可见性。例如 Activity1中有一个EditText 进入此页面不会显示键盘,但是当使用ScrollView 包裹后,进入此页面就会显示键盘了 |
stateUnchanged | 下一个界面的键盘显示状态与当前页面保持一致。 例如Activity2设置了此属性,现在从Activity1导航到Activity2,如果此时键盘是显示的,那么导航Activity2时也是显示的,反之亦然 |
stateHidden | 当一个Activity 被设置为此属性时,我们直接打开此界面键盘是隐藏的,但是从其他界面通过Activity栈返回的就不一定了。例如Activity1设置了此属性,现在从Activity1导航到了Activity2,然后在Activity2中调出键盘,然后finish Activity2 回到Activity1,此时键盘就是显示的了 |
stateAlwaysHidden | 无论何种方式进入此页面时,键盘都是隐藏的 |
stateVisible | 和stateHidden类似,直接打开此页面键盘是显示的,但是从 其他界面通过Activity栈返回的就不一定了。例如Activity1设置了此属性,现在从Activity1导航到了Activity2,然后在Activity2中隐藏键盘,然后finish Activity2 回到Activity1,此时键盘就是隐藏的了 |
stateAlwaysVisible | 和stateAlwaysHidden类似,无论以何种方式进入此页面,键盘都是显示的 |
stateUnspecified
使用ScrollView包裹EditText系统默认会调出键盘
<application
...>
<activity android:name=".MainActivity" >
...
</activity>
...
</application>
stateUnchanged
<application
...>
<activity android:name=".MainActivity"
android:windowSoftInputMode="stateUnspecified">
...
</activity>
<activity android:name=".Activity1" android:windowSoftInputMode="stateUnchanged" />
...
</application>
stateHidden
<application
...>
<activity android:name=".MainActivity"
android:windowSoftInputMode="stateHidden">
...
</activity>
<activity android:name=".Activity1" android:windowSoftInputMode="stateVisible" />
</application>
stateAlwaysHidden
<application
...>
<activity android:name=".MainActivity"
android:windowSoftInputMode="stateAlwaysHidden">
...
</activity>
<activity android:name=".Activity1" android:windowSoftInputMode="stateVisible" />
</application>
stateVisible
与stateHind 相反
stateAlwaysVisible
与stateAlwaysHind 相反
软键盘与Window的布局关系
属性值 | 含义 |
---|---|
adjustResize | 整个window 从底部整体抬升键盘的高度,顶部不会被顶上去,中间区域被下面顶上的内容覆盖。这个效果和你的布局方式有非常大的关系,在一些布局方式中,是没有效果的。 |
adjustPan | 键盘会顶到输入焦点下面,顶部都会被顶上去,输入控件下面的内容会被覆盖 |
adjustUnspecified | 系统的默认设置,系统会根据布局中是否有滚动布局来觉得采用哪种方式,有滚动布局:adjustResize 没有滚动布局adjustPan |
adjustNothing | 布局不发生任何变化,键盘覆盖在布局上面 |
adjustResize
注意:其行为与布局方式相关,所以如果你发现这个属性怎么不起作用的时候,就回头好好看看自己的布局方式。
例如对于如下布局的行为见下面的gif图
布局1
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Activity2">
<TextView
android:id="@+id/tv_des"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="第二个Activity"
android:textColor="@color/colorAccent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="25dp"/>
<EditText
android:id="@+id/et_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toTopOf="@+id/tv_declare"
android:layout_marginBottom="25dp"
android:hint="输入"/>
<TextView
android:id="@+id/tv_declare"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="150dp"
android:textColor="@color/colorPrimaryDark"
android:textSize="15sp"
android:text="ShuSheng007出品,必属精品"/>
</androidx.constraintlayout.widget.ConstraintLayout>
注意我们的EditText是以底部为基准布局的,其上面有可以覆盖的空间,没有定死。
我们再看一种布局,这种布局EditView 直接使用android:layout_marginTop="500dp"
定死了,那这个属性就不起作用了
布局2
androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Activity2">
<TextView
android:id="@+id/tv_des"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="第二个Activity"
android:textColor="@color/colorAccent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="25dp"/>
<EditText
android:id="@+id/et_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_des"
android:layout_marginTop="500dp"
android:hint="输入"/>
<TextView
android:id="@+id/tv_declare"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/et_input"
android:textColor="@color/colorPrimaryDark"
android:layout_marginTop="15dp"
android:textSize="15sp"
android:text="ShuSheng007出品,必属精品"/>
</androidx.constraintlayout.widget.ConstraintLayout>
布局3在布局2的基础上里面加了ScrolView空间
布局3
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Activity2">
<TextView
android:id="@+id/tv_des"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="第二个Activity"
android:textColor="@color/colorAccent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="25dp"/>
<ScrollView
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_des"
app:layout_constraintBottom_toBottomOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="@+id/et_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="500dp"
android:hint="输入"/>
<TextView
android:id="@+id/tv_declare"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/et_input"
android:layout_marginTop="15dp"
android:textColor="@color/colorPrimaryDark"
android:textSize="15sp"
android:text="ShuSheng007出品,必属精品"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
adjustPan
对于布局1 2 3 都起作用,且效果一致,真的很专一啊!
adjustNothing
没什么好演示的,弹出的软键盘直接覆盖在了window上。
如何使用
一个页面的键盘可见性与布局关系可以使用 |
来组合使用,如下所示。<activity android:name=".Activity1" android:windowSoftInputMode="stateVisible|adjustResize" />
使用建议
一般情况下使用默认方式即可,特别是软键盘布局那块,只通过调整我们自己的布局来实现想要的效果。如果你的顶部栏被顶上去了,就好怀疑你的window是事实上使用了adjustPan
方式。
总结
个人觉得这个可以关注了,虽然不难,但是真的是有用,遇到相关问题后可以回来查看一下,正所谓点点关注不迷路,天天都有小惊喜。
最后说一句,我想出去遛一遛,在家半个月了,憋死啦。。。
来源:CSDN
作者:ShuSheng007
链接:https://blog.csdn.net/ShuSheng0007/article/details/104232176