输入法键盘和编辑框焦点

软键盘原理

软件盘的本质是什么?软键盘其实是一个Dialog!
    InputMethodService为我们的输入法创建了一个Dialog,并且将该Dialog的Window的某些参数(如Gravity)进行了设置,使之能够在底部或者全屏显示。当我们点击输入框时,系统对activity主窗口进行调整,从而为输入法腾出相应的空间,然后将该Dialog显示在底部,或者全屏显示。

windowSoftInputMode

主要看这三种模式:adjustResize、adjustPan、adjustUspecified。这些模式是拿来干嘛的呢?试想下,当前一个layout,然后我们点击了某个编辑框,此时会弹出输入法键盘,那输入法键盘很可能遮住部分控件,如下图所示,mmm9、mmm10、mmm11、mmm12、等控件就会被遮住.可是如果我点击的是mmm9,那键盘弹起来,mmm9被遮住了,我就看不到我输入了什么了,这明显是不合理的,所以得调整布局。如何调整呢?主要是adjustResize和adjustPan两种方式。
adjustResize主要是调整原布局的大小,将布局所占的空间和键盘所占的空间独立开来
adjustPan主要是将原布局作为一个ScrollView,进行上移,这样就可以保证要输入的位置可以看到,不被遮住。
  
  

adjustResize

在软键盘弹出或者收起的时候会调用 onSizeChanged方法,原页面大小会变化,比如原布局为720*1280,弹起输入法键盘时,键盘大小为720*550,那么原布局会改变大小,1280-550=730,原页面会变为720*730,可能这么说还不明白,看图就懂了
    

提交按钮位于layout的最底部,当输入法键盘弹出的时候,layout的高度减少,按钮依然位于layout的最底部,这就是resize,layout大小会改变,会重新测量重新布局,xml代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <EditText
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:hint="输入" />

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="horizontal">

        <Button
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="提交"
            android:layout_gravity="bottom"/>

    </LinearLayout>

</LinearLayout>

adjustPan

adjustPan主要是将原布局作为一个ScrollView,进行上移,这样就可以保证要输入的位置可以看到,不被遮住。看下图可以清楚看到上移,上移就是为了当前编辑框不被遮住.注意不是一定会上移的,如果在当前位置弹出键盘,不会挡住编辑框,那就直接弹出。输入法是盖在原布局之上的,会盖住部分。
  

结论

看看官方文档
adjustResize:
The activity's main window is always resized to makeroom for the soft keyboard on screen.
adjustPan:
The activity's main window is not resized to make roomfor the soft keyboard. Rather, the contents of the window are automaticallypanned so that the current focus is never obscured by the keyboard and userscan always see what they are typing. This is generally less desirable thanresizing, because the user may need to close the soft keyboard to get at andinteract with obscured parts of the window.

adjustUnspecified:
It is unspecified whether the activity's main window resizes to make room for the soft keyboard, or whether the contents of the window pan to make the current focus visible on-screen. The system will automatically select one of these modes depending on whether the content of the window has any layout views that can scroll their contents. If there is such a view, the window will be resized, on the assumption that scrolling can make all of the window's contents visible within a smaller area.

This is the default setting for the behavior of the main window


个人感觉,都是为了布局更合理adjustResize使用改变布局的大小,adjustPan使用上移的方式。adjustResize会多调用一个onResize函数。 adjustUnspecified就是系统根据是否有可滚动的view来选择adjustResize还是adjustPan。以下例子就是adjustUnspecified选择了adjustResize的情况
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    >
    <LinearLayout
        android:background="#ff0000"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical"
        android:layout_weight="1.0">
        <ScrollView
            android:background="#00ff00"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:fillViewport="true"
            android:orientation="vertical"
            android:scrollbars="vertical">
            <EditText
                android:id="@+id/gridview"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"/>

        </ScrollView>
    </LinearLayout>
    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_gravity="center_horizontal"
        android:paddingLeft="20dp"
        android:paddingRight="20dp">
        <Button android:id="@+id/smit_btn"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="上 传"
            android:layout_weight="1.0"/>

        <Button android:id="@+id/cancel_btn"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1.0"
            android:text="取 消" />"

    </LinearLayout>
</LinearLayout>



监听软键盘弹出收起

系统未提供相应api,只有adjustResize类型的activity,可以通过监听onResize来监控键盘的弹出收起,弹出收起的时候都会调用onResize,可参考http://blog.csdn.net/lilu_leo/article/details/6587578

手动展示软键盘

	protected void showKeyboard(boolean isShow) {
		InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
		if (isShow) {
			if (getCurrentFocus() == null) {
				imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
			} else {
				imm.showSoftInput(getCurrentFocus(), 0);
			}
		} else {
			if (getCurrentFocus() != null) {
				imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
			}
		}
	}

点击编辑框上移

要想实现点击编辑框之后,页面整个向上移动可以采用外包scrollview的方法,具体可见http://ipjmc.iteye.com/blog/1439657,
当然也可以通过监听软键盘的弹出和收起,然后自己改变布局,在onResize里post(或者postDelay)一个runnable,runnable里改变布局

本文代码在EditClickUp内

禁止软键盘弹出

对于某些activity,内部有EditText,那已进入此界面就会弹出软键盘,要想不弹软键盘怎么办
android:windowSoftInputMode="stateAlwaysHidden"

参考资料

http://blog.csdn.net/lilu_leo/article/details/6587578
http://ipjmc.iteye.com/blog/1439657



猜你喜欢

转载自blog.csdn.net/litefish/article/details/46313785