Android键盘面板冲突 布局闪动处理方案

来源:互联网 发布:mysql 2002错误 编辑:程序博客网 时间:2024/06/05 16:20

JKeyboardPanelSwitch

起源,之前在微信工作的时候,为了给用户带来更好的基础体验,做了很多尝试,踩了很多输入法的坑,特别是动态调整键盘高度,二级页面是透明背景,魅族早期的Smart bar等, 后来逐一完善了,考虑到拥抱开源,看业界还是有很多应用存在类似问题。就有了这个repo

之前有写过一篇核心思想:Switching between the panel and the keyboard in Wechat

android软键盘挡住输入框问题解决方法

1、EditText有焦点(focusable为true)阻止输入法弹出

editText=(EditText)findViewById(R.id.txtBody);editText.setOnTouchListener(new OnTouchListener() {    public boolean onTouch(View v, MotionEvent event) {        editText.setInputType(InputType.TYPE_NULL); // 关闭软键盘         return false;    }});

2、当EidtText无焦点(focusable=false)时阻止输入法弹出

InputMethodManager imm = (InputMethodManager)getSystemService(INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);

3.调用显示系统默认的输入法

方法一、
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);

imm.showSoftInput(m_receiverView(接受软键盘输入的视图(View)),InputMethodManager.SHOW_FORCED(提供当前操作的标记,SHOW_FORCED表示强制显示));

方法二、
Java代码 InputMethodManager m=(InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
m.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS); (这个方法可以实现输入法在窗口上切换显示,如果输入法在窗口上已经显示,则隐藏,如果隐藏,则显示输入法到窗口上)

4.调用隐藏系统默认的输入法

((InputMethodManager)getSystemService(INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(WidgetSearchActivity.this.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); (WidgetSearchActivity是当前的Activity)

5.获取输入法打开的状态

InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
boolean isOpen=imm.isActive();
isOpen若返回true,则表示输入法打开

参数 含义 WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN 软键盘直接覆盖Activity,通常这是默认值 WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE Activity高度会变化,让出软键盘的空间。和WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN 为2选1的值 WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE Activity一打开就直接显示软键盘窗口,如果该窗口需要的话(即有EditText,或有ditable的控件) WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN Activity打开后并不直接显示软键盘窗口,直到用户自己touch文本框。


大家在布局时候,有时候会发现输入框被挡住一部分,能完全显示出来,但是系统自带短信界面
可以完全漂浮在软键盘之上,看了一下短信源码,修改一下输入模式就可以了,源码如下
代码方式:

getWindow().setSoftInputMode(                WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE |                WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); 

也可以简单点:

getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);

xml方式:

<activity     android:name=".Activity.FilterActivity"     android:label="@string/app_name"      android:windowSoftInputMode="stateHidden"     android:screenOrientation="portrait"     android:configChanges="keyboardHidden|orientation"/>

下面做个详细的介绍:

软输入法模式选项:
public int softInputMode;

以下选项与输入法模式有关:
软输入区域是否可见。
public static final int SOFT_INPUT_MASK_STATE = 0x0f;

未指定状态。
public static final int SOFT_INPUT_STATE_UNSPECIFIED = 0;

不要修改软输入法区域的状态。
public static final int SOFT_INPUT_STATE_UNCHANGED = 1;

隐藏输入法区域(当用户进入窗口时)。
public static final int SOFT_INPUT_STATE_HIDDEN = 2;

当窗口获得焦点时,隐藏输入法区域。
public static final int SOFT_INPUT_STATE_ALWAYS_HIDDEN = 3;

显示输入法区域(当用户进入窗口时)。
public static final int SOFT_INPUT_STATE_VISIBLE = 4;

当窗口获得焦点时,显示输入法区域。
public static final int SOFT_INPUT_STATE_ALWAYS_VISIBLE = 5;

窗口应当主动调整,以适应软输入窗口。
public static final int SOFT_INPUT_MASK_ADJUST = 0xf0;

未指定状态,系统将根据窗口内容尝试选择一个输入法样式。
public static final int SOFT_INPUT_ADJUST_UNSPECIFIED = 0x00;

当输入法显示时,允许窗口重新计算尺寸,使内容不被输入法所覆盖。
不可与SOFT_INPUT_ADJUSP_PAN混合使用;如果两个都没有设置,系统将根据窗口内容自动设置一个选项。
public static final int SOFT_INPUT_ADJUST_RESIZE = 0x10;

输入法显示时平移窗口。它不需要处理尺寸变化,框架能够移动窗口以确保输入焦点可见。
不可与SOFT_INPUT_ADJUST_RESIZE混合使用;如果两个都没有设置,系统将根据窗口内容自动设置一个选项。
public static final int SOFT_INPUT_ADJUST_PAN = 0x20;

当用户转至此窗口时,由系统自动设置,所以你不要设置它。
当窗口显示之后该标志自动清除。
public static final int SOFT_INPUT_IS_FORWARD_NAVIGATION = 0x100;

EditText导致的界面上移、挡住、挤压等问题

http://blog.csdn.net/biezhihua/article/details/51049689

布局中使用了EditText和RecyclerView,软键盘弹出的时候会将界面也向上面挤

//输入框处于中下的位置,这样的话,键盘可能挡住输入框android:windowSoftInputMode = "adjustResize" //调整屏幕的大小以便留出软键盘的空间//输入框处于偏上面,发生挤压android:windowSoftInputMode = "adjustPan" android:windowSoftInputMode = "stateHidden"android:fitsSystemWindows="true"

使软键盘不全屏显示,只占用一部分屏幕同时,这个属性还能控件软键盘右下角按键的显示内容,默认情况下为回车键

android:imeOptions="flagNoExtractUi"
setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);

Android中软键盘的使用是非常多的,下面为软键盘常用的设置;

1、横屏时,点击输入框出现全键盘解决方案: 在EditText、searchview等控件中加

android:imeOptions="flagNoExtractUi"

2、竖屏时,安卓会出现半屏。
case1:你的输入框处于中下的位置,这样的话,键盘可能挡住输入框。 解决方法:在manifest中对activity设置

android:windowSoftInputMode="adjustResize"

这样activity的主窗口总会resize为键盘提供空间
case2:你的输入框处于偏上面,一般情况下这样就不会有什么问题,但是如果你的界面纵向方面使用的是layout_weight即比重来分布页面的话,
软件盘会压缩整个window,导致输入框部分被压缩。 解决方法:在manifest中对activity设置

android:windowSoftInputMode="adjustPan"

这样键盘不会对压缩原窗口,只会遮盖下面一部分内容。这样输入框不会被压缩了。

3、刚进入一个activity,会focus 输入框,这时会主动弹出软键盘,如果不希望自动弹出,那么可先让其他的不重要的控件获取焦点,然后一个定时器

再让EditText获取焦点即可!

4、判断软键盘当前是否处于弹出状态

if(getWindow().getAttributes().softInputMode==WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE)

5、手动隐藏软键盘

getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);

6、手动弹出软键盘
((InputMethodManager)getSystemService(INPUT_METHOD_SERVICE)).toggleSoftInput(0,InputMethodManager.HIDE_NOT_ALWAYS);

自动弹出软键盘

刚进入activity的时候,如果布局组件有edittext的话,往往edittext会获取焦点,自动弹出软键盘,影响整个界面的视觉效果。解决方法如下:

可以在edittext的父布局结构中(例如LinearLayout,RelativeLayout等)添加

android:focusable="true" android:focusableInTouchMode="true"

或者

<activity    android:name=".MainActivity"    android:windowSoftInputMode="stateHidden" ></activity>

Android中的windowSoftInputMode属性详解

这篇文章主要介绍了Android中的windowSoftInputMode属性详解,本文对windowSoftInputMode的9个属性做了详细总结,需要的朋友可以参考下

在前面的一篇文章中,简单的介绍了一下如何实现软键盘不自动弹出,使用的方法是设置android:windowSoftInputMode属性。那么,这个属性到底是干什么的,他有什么作用呢?今天这篇文章,就是探索android:windowSoftInputMode属性的作用的。

首先,我们从这个属性的名称中,可以很直观的看出它的作用,这个属性就是来设置窗口软键盘的交互模式的。

android:windowSoftInputMode属性一共有9个取值,分别是:

  • stateUnspecified
  • stateUnchanged
  • stateHidden
  • stateAlwaysHidden
  • stateVisible
  • stateAlwaysVisible
  • adjustUnspecified
  • adjustResize
  • adjustPan

我们设置属性的时候,可以在这9个值里面选择一个,也可以用”state…|adjust”的形式进行设置。那么,这些取值到底是怎么影响到软键盘与窗口之间的交互的呢?下面,我们就一个个的测试这9个取值,到底是如何影响软键盘的显示的。

1.stateUnspecified

中文意思是未指定状态,当我们没有设置android:windowSoftInputMode属性的时候,软件默认采用的就是这种交互方式,系统会根据界面采取相应的软键盘的显示模式,比如,当界面上只有文本和按钮的时候,软键盘就不会自动弹出,因为没有输入的必要。那么,当界面上出现了获取了焦点的输入框的时候,软键盘会不会自动的弹出呢?这个还真不一定!比如,在下面的这个界面布局中,软键盘并不会自动弹出。

就是说,默认的,在这种界面情况下,系统并不确定用户是否需要软键盘,因此不会自动弹出。但是,为什么说不一定呢?这是因为,如果我们在这个布局的外面,包裹上一个ScrollView,软键盘就会自动的弹出来了!如下,在这种布局文件下,软键盘会自动的弹出

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical" >    <ScrollView        android:layout_width="match_parent"        android:layout_height="match_parent" >        <LinearLayout            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:orientation="vertical" >            <Button                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:onClick="toOther"                android:text="跳转" />            <EditText                android:layout_width="match_parent"                android:layout_height="wrap_content" />        </LinearLayout>    </ScrollView></LinearLayout>

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

2. stateUnchanged

中文的意思就是状态不改变的意思,我们应该怎么理解这句话呢?其实很好理解,就是说,当前界面的软键盘状态,取决于上一个界面的软键盘状态。举个例子,假如当前界面键盘是隐藏的,那么跳转之后的界面,软键盘也是隐藏的;如果当前界面是显示的,那么跳转之后的界面,软键盘也是显示状态。

3. stateHidden

顾名思义,如果我们设置了这个属性,那么键盘状态一定是隐藏的,不管上个界面什么状态,也不管当前界面有没有输入的需求,反正就是不显示。因此,我们可以设置这个属性,来控制软键盘不自动的弹出。

4. stateAlwaysHidden

这个属性也可以让软键盘隐藏,但是我暂时还不知道和stateHidden属性的区别,本来想去stackOverFlow上问一下的,但是,Great Wall,呵呵呵…祝愿病魔早日战胜方校长

5.stateVisible

设置为这个属性,可以将软键盘召唤出来,即使在界面上没有输入框的情况下也可以强制召唤出来。

6.stateAlwaysVisible

这个属性也是可以将键盘召唤出来,但是与stateVisible属性有小小的不同之处。举个例子,当我们设置为stateVisible属性,如果当前的界面键盘是显示的,当我们点击按钮跳转到下个界面的时候,软键盘会因为输入框失去焦点而隐藏起来,当我们再次回到当前界面的时候,键盘这个时候是隐藏的。但是如果我们设置为stateAlwaysVisible,我们跳转到下个界面,软键盘还是隐藏的,但是当我们再次回来的时候,软键盘是会显示出来的。所以,这个Always就解释了这个区别,不管什么情况到达当前界面(正常跳转或者是上一个界面被用户返回),软键盘都是显示状态。说到这里,我联想到了上面的stateHidden和stateAlwaysHidden,我估计区别也是这样的,就是说,stateAlwaysHidden无论如何都是隐藏的,但是如果在跳转到下个界面的时候,软键盘被召唤出来了,那么当下个界面被用户返回的时候,键盘应该是不会被隐藏的,但是,我还没有找到能够跳转到下个界面,还让当前界面软键盘不消失的方法,所以暂时不能验证。

7.adjustUnspecified

从这个属性开始,就不是设置软键盘的显示与隐藏模式了,而是设置软键盘与软件的显示内容之间的显示关系。当你跟我们没有设置这个值的时候,这个选项也是默认的设置模式。在这中情况下,系统会根据界面选择不同的模式。如果界面里面有可以滚动的控件,比如ScrowView,系统会减小可以滚动的界面的大小,从而保证即使软键盘显示出来了,也能够看到所有的内容。如果布局里面没有滚动的控件,那么软键盘可能就会盖住一些内容,我们从下面的图中可以看出差别。

没有滚动控件,软键盘下面的布局都被遮挡住了,若想修改,只能隐藏软键盘,然后选择。而且,重点注意一下上面的布局,当我们选择的输入框偏下的时候,上面的标题栏和布局被软键盘顶上去了。记住这个特征,因为后面有个属性和这个的效果不一样。

布局里面有滑动控件,系统会自动的缩小整个界面的大小,因此,我们可以软键盘上面的小区域中显示所有的输入框。

这就是两中显示模式之间的差别。

8. adjustResize

这个属性表示Activity的主窗口总是会被调整大小,从而保证软键盘显示空间。
我们先看显示效果。
注意观察这个上面的标题栏和按钮,设置为adjustResize属性之后,对于没有滑动控件的布局,虽然还是不能选择所有的输入框,但是,窗口的显示方式发生了变化,默认属性时,整个布局是被顶上去了,但是设置为adjustResize属性,布局的位置并没有发生什么变化,这就是最大的区别。

而对于有滑动控件的布局来说,显示效果和默认是一样的。

9. adjustPan

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

当我们点击5这个输入框,我们会发现下面的现象。
最上面只能够显示到按钮,标题栏已经不能看到了。

而最下面也只能滑动到8,下面的内容也不能够滑动了。

因此,我们就能够理解这个属性的作用了。
通过以上的实验,我们可以得出结论,如果我们不设置”adjust…”的属性,对于没有滚动控件的布局来说,采用的是adjustPan方式,而对于有滚动控件的布局,则是采用的adjustResize方式。
了解了上面的这些知识之后,我们就可以根据自己的需求设置不同的方式了。而且,关于如何使得界面加载的时候不显示软键盘,我们也有了一个很清楚的认识。

0 0