Activity下WindowSoftInputMode属性详解

最近在做一个银行的项目,所以需要自定义键盘,不再使用系统的键盘了,从中也遇到了很多问题,比如怎么控制系统键盘不弹出,然后怎么控制软键盘与当前Activity的交互,是时候了解下WindowSoftInputMode了,这个属性就是来设置窗口软键盘的交互模式的。

它总共有9种状态,官方给的9种状态的解释大概如下:
【1】stateUnspecified:软键盘的状态并没有指定,系统将选择一个合适的状态或依赖于主题的设置

【2】stateUnchanged:当这个activity出现时,软键盘将一直保持在上一个activity里的状态,无论是隐藏还是显示

【3】stateHidden:用户选择activity时,软键盘总是被隐藏

【4】stateAlwaysHidden:当该Activity主窗口获取焦点时,软键盘也总是被隐藏的

【5】stateVisible:软键盘通常是可见的

【6】stateAlwaysVisible:用户选择activity时,软键盘总是显示的状态

【7】adjustUnspecified:默认设置,通常由系统自行决定是隐藏还是显示

【8】adjustResize:该Activity总是调整屏幕的大小以便留出软键盘的空间

【9】adjustPan:当前窗口的内容将自动移动以便当前焦点从不被键盘覆盖和用户能总是看到输入内容的部分

下面我们结合Demo一个一个来讲这几个属性。

1、stateUnspecified中文意思是未指定状态,当我们没有设置android:windowSoftInputMode属性的时候,软件默认采用的就是这种交互方式,系统会根据界面采取相应的软键盘的显示模式,比如,当界面上只有文本和按钮的时候,软键盘就不会自动弹出,因为没有输入的必要。那么,当界面上出现了获取了焦点的输入框的时候,软键盘会不会自动的弹出呢?这个还真不一定!比如,在下面的这个界面布局中,软键盘并不会自动弹出。
我们还是借用上一篇博客的例子,运行下可见当我们把android:windowSoftInputMode设置为stateUnspecified的时候:
这里写图片描述
**可见,启动Activity的时候键盘并没有自动弹起来,
当我们嵌套一个ScrollView在最外面的时候,再次启动Acitivty,我们看一下效果:**
这里写图片描述
键盘成功弹起,我们发现当有自动获取焦点的EditText嵌套在可滑动的View中的时候,键盘默认是弹出的。所以隐藏键盘另外一种方式可以让EditText失去焦点,我们把EditText的focus设置false试一下:
这里写图片描述

我们发现,键盘不再弹起来了,尽管是嵌套了一个ScrollView,我们接着把第一个EditText设置为android:focusable=”false”,我们发现焦点聚焦在了第二个,键盘照样弹起了,这也验证了我们的猜测。

总结:当设置属性为stateUnspecified的时候,系统是默认不弹出软键盘的,但是当有获得焦点的输入框的界面有滚动的需求的时候,会自动弹出软键盘。至于为什么非要强调要获取焦点的输入框,这是因为,如果不是输入框获取焦点,软键盘也是不会自动弹出的,让界面不自动弹出软键盘的其中一个解决方案,就是在xml文件中,设置一个非输入框控件获取焦点,从而阻止键盘弹出。

2、stateUnchanged 中文的意思就是状态不改变的意思,我们应该怎么理解这句话呢?其实很好理解,就是说,当前界面的软键盘状态,取决于上一个界面的软键盘状态。举个例子,假如当前界面键盘是隐藏的,那么跳转之后的界面,软键盘也是隐藏的;如果当前界面是显示的,那么跳转之后的界面,软键盘也是显示状态。
我们换一个demo测试一下啦,
我们A中是有EditText跟一个Button嵌套了一个ScrollView,默认也就是弹起键盘的,B页面上面都没有,就一个EditText,我们从A跳转到B,默认A界面是会弹起键盘的,我们看看B界面有没有弹起界面(B界面设置为android:windowSoftInputMode=”stateUnchanged”):
这里写图片描述

**可以得出结论了:
当前界面的软键盘状态,取决于上一个界面的软键盘状态。**

**3.stateHidden
顾名思义,如果我们设置了这个属性,那么键盘状态一定是隐藏的,不管上个界面什么状态,也不管当前界面有没有输入的需求,反正就是不显示。因此,我们可以设置这个属性,来控制软键盘不自动的弹出。**
尽管我们A页面中有嵌套一个可滑动的ScrollView,但是键盘依然没有弹出:
这里写图片描述

4、stateAlwaysHidden:当该Activity主窗口获取焦点时,软键盘也总是被隐藏的
跟stateHidden感觉没什么差别啊,好像我没有发现有什么差别咯,

5、stateVisible:软键盘通常是可见的, 设置为这个属性,可以将软键盘召唤出来,即使在界面上没有输入框的情况下也可以强制召唤出来。
我们把EditText设置成Gone,然后看一下会不会弹出键盘:
这里写图片描述
可以看到,键盘照样是弹起来了,这也证明了这一点,那么让我跳转到B的时候,再回到A的时候看看键盘还在不在?
经过测试,发现如果A设置了stateVisible,跳转到B,B中键盘任然出现,再按返回键回到A的时候,A中键盘不会出现了。

6、stateAlwaysVisible:用户选择activity时,软键盘总是显示的状态跟5中唯一不同就是,如果A设置了stateAlwaysVisible,跳转到B,B中键盘任然出现,再按返回键回到A的时候,A中键盘还会出现。

7、adjustUnspecified:默认设置,通常由系统自行决定是隐藏还是显示
首先我们不嵌套ScrollView,

  <LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:gravity="center_horizontal"
        >
        <EditText
        android:id="@+id/id_edit1"
        android:layout_width="match_parent"
        android:layout_height="50dp" />
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="确定"
            android:onClick="click"
            />
    </LinearLayout>

经过测试发现,键盘没有弹起,
我们加一个ScrollView再试一下
经过测试会弹出键盘,
我们在EditText上面加一个ListView

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    >
    <ListView
        android:divider="@null"
        android:id="@+id/id_list"
        android:layout_weight="1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"></ListView>
    <LinearLayout
        android:layout_alignParentBottom="true"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:gravity="center_horizontal"
        >
        <EditText
        android:id="@+id/id_edit1"
        android:layout_width="match_parent"
        android:layout_height="50dp" />
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="确定"
            android:onClick="click"
            />
    </LinearLayout>
</LinearLayout>

然后在ListView的item设置为EditText,我们发现键盘并没有弹出,因为有很多EditText,系统也不知道该聚焦哪一个,所以键盘并未有弹起。
点击底部EditText:
这里写图片描述
点击ListView中的EditText:
这里写图片描述
发现底下的EditText被顶起来了。
总结:系统会调整整个布局整体的位置,使输入的部分始终可见。因此底部的布局被顶上去了,“标题栏”不会被顶上去,“确定”按钮还是可见的。

8、adjustResize:该Activity总是调整屏幕的大小以便留出软键盘的空间
我们只放一个EditText跟一个Button放在RelativeLayout的底部,
当为”adjustResize”的时候:自动弹出键盘,然后“确定”按钮可见,标题栏没有消失,
当为“adjustUnspecified”的时候:“确定按钮”看不到了,“标题栏”消失:
这里写图片描述

当为“adjustPan”的时候:“确定按钮”看不到了,“标题栏”同样消失。
因此,我们就能够理解这个属性的作用了。
通过以上的实验,我们可以得出结论,如果我们不设置”adjust…”的属性,对于没有滚动控件的布局来说,采用的是adjustPan方式,而对于有滚动控件的布局,则是采用的adjustResize方式。

9.adjustPan 如果设置为这个属性,那么Activity的屏幕大小并不会调整来保证软键盘的空间,而是采取了另外一种策略,系统会通过布局的移动,来保证用户要进行输入的输入框肯定在用户的失业范围里面,从而让用户可以看到自己输入的内容。对于没有滚动控件的布局来说,这个其实就是默认的设置,如果我们选择的位置偏下,上面的标题栏和部分控件会被顶上去。但是对于有滚动控件的布局来说,则不太一样,

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    >
    <ListView
        android:divider="@null"
        android:id="@+id/id_list"
        android:layout_weight="1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"></ListView>
    <LinearLayout
        android:layout_alignParentBottom="true"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:gravity="center_horizontal"
        >
        <EditText
        android:id="@+id/id_edit1"
        android:layout_width="match_parent"
        android:layout_height="50dp" />
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="确定"
            android:onClick="click"
            />
    </LinearLayout>
</LinearLayout>

点击底部EditText:
这里写图片描述

点击ListView中的EditText:
这里写图片描述

总结:始终会调整屏幕的大小,键盘出现在你点击的EditText的下面。

好了! 9种状态都讲完了,有很多状态我也不是很明白啊,期待更好的解释,或者你有什么更好的文档可以推荐一下啊,嘻嘻!!

最后说一下我项目中的需求:就是类似于qq的评论框弹出一样
“标题栏不消失”“确定按钮可见”“默认不弹出键盘”

于是用到了: android:windowSoftInputMode=”adjustResize|stateAlwaysHidden”
这两个属性完美的解决了我的需求。。
完啦!~~ 3Q

猜你喜欢

转载自blog.csdn.net/zuo_er_lyf/article/details/80269938
今日推荐