秒懂Android开发之 android:windowSoftInputMode 属性详解

允我心安 提交于 2020-02-09 20:12:45

【版权申明】非商业目的可自由转载
博文地址: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, Activity1Activity2

属性值 含义
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方式。

总结

个人觉得这个可以关注了,虽然不难,但是真的是有用,遇到相关问题后可以回来查看一下,正所谓点点关注不迷路,天天都有小惊喜。

最后说一句,我想出去遛一遛,在家半个月了,憋死啦。。。

哪里可以找到我?
Gitbub
个人博客

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!