关闭

Android软键盘弹出引起的各种不适终极解决方案

标签: androidlayout输入法class测试
68862人阅读 评论(19) 收藏 举报
分类:

        很多写登录界面的开发者都会遇到一个问题:那就是在登录界面时,当你点击输入框时,下边的按钮有时会被输入框挡住,这个不利于用户的体验,所以很多人希望软键盘弹出时,也能把按钮挤上去。很多开发者想要监听键盘的状态,这无疑是一个很麻烦的做法。

       我们可以在AndroidManifest.xml的Activity设置属性:android:windowSoftInputMode = "adjustResize" ,软键盘弹出时,要对主窗口布局重新进行布局,并调用onSizeChanged方法,切记一点当我们设置为“adjustResize”时,我们的界面不要设置为全屏模式,否则设置了这个属性也不会有什么效果。而当我们设置android: windowSoftInputMode = "adjustPan"时,主窗口就不会调用onSizeChanged方法,界面的一部分就会被软键盘覆盖住,就不会被挤到软键盘之上了。

我们通过一段代码来测试一下,当我们设置了该属性后,弹出输入法时,系统做了什么:

重写Layout布局:

  1.     public class ResizeLayout extends LinearLayout{ 
            private static int count = 0; 
             
            public ResizeLayout(Context context, AttributeSet attrs) { 
                super(context, attrs); 
            } 
             
            @Override 
            protected void onSizeChanged(int w, int h, int oldw, int oldh) {     
                super.onSizeChanged(w, h, oldw, oldh); 
                 
                Log.e("onSizeChanged " + count++, "=>onResize called! w="+w + ",h="+h+",oldw="+oldw+",oldh="+oldh); 
            } 
             
            @Override 
            protected void onLayout(boolean changed, int l, int t, int r, int b) { 
                super.onLayout(changed, l, t, r, b); 
                Log.e("onLayout " + count++, "=>OnLayout called! l=" + l + ", t=" + t + ",r=" + r + ",b="+b); 
            } 
             
            @Override 
            protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
                super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
                 
                Log.e("onMeasure " + count++, "=>onMeasure called! widthMeasureSpec=" + widthMeasureSpec + ", heightMeasureSpec=" + heightMeasureSpec); 
            } 

我们的布局设置为:
  1.     <com.winuxxan.inputMethodTest.ResizeLayout  
            xmlns:android="http://schemas.android.com/apk/res/android" 
            android:id="@+id/root_layout" 
            android:layout_width="fill_parent" 
            android:layout_height="fill_parent" 
            android:orientation="vertical" 
            > 
             
            <EditText 
                android:layout_width="fill_parent"  
                android:layout_height="wrap_content"  
            /> 
           
            <LinearLayout 
                    android:id="@+id/bottom_layout" 
                    android:layout_width="fill_parent"  
                    android:layout_height="fill_parent"  
                    android:orientation="vertical" 
                    android:gravity="bottom">s 
            
            <TextView   
                android:layout_width="fill_parent"  
                android:layout_height="wrap_content"  
                android:text="@string/hello" 
                android:background="#77777777" 
              /> 
           </LinearLayout> 
        </com.winuxxan.inputMethodTest.ResizeLayout> 

AndroidManifest.xml的Activity设置属性:android:windowSoftInputMode = "adjustResize"
    运行程序,点击文本框,查看调试信息:
    E/onMeasure 6(7960): =>onMeasure called! widthMeasureSpec=1073742144, heightMeasureSpec = 1073742024
    E/onMeasure 7(7960): =>onMeasure called! widthMeasureSpec=1073742144, heightMeasureSpec = 1073742025
    E/onSizeChanged 8(7960): =>onSizeChanged called! w=320,h=201,oldw=320,oldh=377
    E/onLayout 9(7960): =>OnLayout called! l=0, t=0,r=320,b=201
    从调试结果我们可以看出,当我们点击文本框后,根布局调用了onMeasure,onSizeChanged和onLayout。

  windowSoftInputMode的值如果设置为adjustPan,那么该Activity主窗口并不调整屏幕的大小以便留出软键盘的空间。相反,当前窗口的内容将自动移动以便当前焦点从不被键盘覆盖和用户能总是看到输入内容的部分。这个通常是不期望比调整大小,因为用户可能关闭软键盘以便获得与被覆盖内容的交互操作。
    上面的例子中,我们将AndroidManifest.xml的属性进行更改:android: windowSoftInputMode = "adjustPan"

    重新运行,并点击文本框,查看调试信息:
    E/onMeasure 6(8378): =>onMeasure called! widthMeasureSpec=1073742144, heightMeasureSpec=1073742200
    E/onMeasure 7(8378): =>onMeasure called! widthMeasureSpec=1073742144, heightMeasureSpec=1073742201
    E/onLayout 8(8378): =>OnLayout called! l=0, t=0,r=320,b=377
    我们看到:系统也重新进行了measrue和layout,但是我们发现,layout过程中onSizeChanged并没有调用,这说明输入法弹出前后并没有改变原有布局的大小。

当然还有其他属性可以设置:

"stateUnspecified"

软键盘的状态(是否它是隐藏或可见)没有被指定。系统将选择一个合适的状态或依赖于主题的设置。

这个是为了软件盘行为默认的设置。

"stateUnchanged"

软键盘被保持无论它上次是什么状态,是否可见或隐藏,当主窗口出现在前面时。

"stateHidden"

当用户选择该Activity时,软键盘被隐藏——也就是,当用户确定导航到该Activity时,而不是返回到它由于离开另一个Activity。

"stateAlwaysHidden"

软键盘总是被隐藏的,当该Activity主窗口获取焦点时。

"stateVisible"

软键盘是可见的,当那个是正常合适的时(当用户导航到Activity主窗口时)。

"stateAlwaysVisible"

当用户选择这个Activity时,软键盘是可见的——也就是,也就是,当用户确定导航到该Activity时,而不是返回到它由于离开另一个Activity。

"adjustUnspecified"

它不被指定是否该Activity主窗口调整大小以便留出软键盘的空间,或是否窗口上的内容得到屏幕上当前的焦点是可见的。系统将自动选择这些模式中一种主要依赖于是否窗口的内容有任何布局视图能够滚动他们的内容。如果有这样的一个视图,这个窗口将调整大小,这样的假设可以使滚动窗口的内容在一个较小的区域中可见的。这个是主窗口默认的行为设置。

"adjustResize"

该Activity主窗口总是被调整屏幕的大小以便留出软键盘的空间

"adjustPan"

该Activity主窗口并不调整屏幕的大小以便留出软键盘的空间。相反,当前窗口的内容将自动移动以便当前焦点从不被键盘覆盖和用户能总是看到输入内容的部分。这个通常是不期望比调整大小,因为用户可能关闭软键盘以便获得与被覆盖内容的交互操作。



 


12
2
查看评论

在androidMainfest.xml文件中在此Activity中写入 android:windowSoftInputMode="adjustPan" 可以让界面不被弹出的键盘挤上去。

在androidMainfest.xml文件中在此Activity中写入 android:windowSoftInputMode="adjustPan"  可以让界面不被弹出的键盘挤上去。
  • xiaodongvtion
  • xiaodongvtion
  • 2012-03-29 13:59
  • 14359

彻底搞定Android开发中软键盘的常见问题

软键盘显示的原理       软件盘的本质是什么?软键盘其实是一个Dialog。        InputMethodService为我们的输入法创建了一个Dialog,并且将该Dialog的Window的某些参数(如...
  • mynameishuangshuai
  • mynameishuangshuai
  • 2016-06-02 15:11
  • 53360

android:windowSoftInputMode属性详解

android:windowSoftInputMode activity主窗口与软键盘的交互模式,可以用来避免输入法面板遮挡问题,Android1.5后的一个新特性。 这个属性能影响两件事情: 【一】当有焦点产生时,软键盘是隐藏还是显示 【二】是否减少活动主窗口大小以便腾出空...
  • twoicewoo
  • twoicewoo
  • 2012-03-22 18:54
  • 162893

你知道android:windowSoftInputMode="adjustResize" 与adjustPan的区别吗

印象中,一个会把布局顶起来,一个不会。想了解详细的可以参见彻底搞定Android开发中软键盘的常见问题但是,在我最近的项目中发现adjustPan不起作用。*而且,在代码中调用*public static void openSoftKeyboard(@NonNull Activity context...
  • DucklikeJAVA
  • DucklikeJAVA
  • 2017-03-13 16:00
  • 2294

android 软键盘挡住输入内容,adjustResize设置了也无效

键盘弹出时,会将布局底部的导航条顶上去。 先给出很多文章中给出的解决办法如下: 在mainfest.xml中,在和导航栏相关的activity中加: ? 1 2 3 4 activity  and...
  • zhuawalibai
  • zhuawalibai
  • 2017-08-04 10:43
  • 270

使用adjustResize属性笔记

要使用adjustResize的属性必须要先布局好,当然前提是这个activity不能是Fullscreen的,否则设置的adjustResize将失效,这句我是看网上别人说的,具体没测试。 目前项目中的不是FullScreen,但是由于是别人写的布局代码,然后发现在配置文件里配置了adjustRe...
  • fancylovejava
  • fancylovejava
  • 2014-06-30 23:12
  • 9483

Android 设置状态栏后adjustResize属性无效

这两天被这个问题搞得很焦灼,今天终于解决了,在这里把自己解决的办法分享一下; 这是之前碰到的问题 如截图所示,输入框被遮住了 之前试过AndroidBug5497Workaround这个类,但发现在有些手机上无法做到适配,于是又到处找,最后终于找到了一种方法。 首先在对应的A...
  • qq_24737357
  • qq_24737357
  • 2016-06-12 11:44
  • 2201

解决android 软键盘在全屏下设置adjustResize无效的问题

全屏模式下,即使将activity的windowSoftInputMode的属性设置为:adjustResize,在键盘显示时它未将Activity的Screen向上推动,所以你Activity的view的根树的尺寸是没有变化的。在这种情况下,你也就无法得知键盘的尺寸,对根view的作相应的推移。全...
  • xiechengfa
  • xiechengfa
  • 2016-04-11 16:30
  • 5620

Android全屏和adjustResize的冲突解决

场景:当activity设置了全屏,需要布局随着软键盘的弹起而向上推动坑1:全屏属性和属性adjustResize冲突解决办法:package com.xunniu.ybk.utils;import android.app.Activity; import android.graphics.Rect...
  • plq690816
  • plq690816
  • 2016-05-11 15:25
  • 1808

windowSoftInputMode属性介绍及设置adjustResize不起作用的解决方案

android:windowSoftInputMode activity主窗口与软键盘的交互模式,可以用来避免输入法面板遮挡问题,Android1.5后的一个新特性。 这个属性能影响两件事情: 【一】当有焦点产生时,软键盘是隐藏还是显示 【二】是否减少活动主窗口大小以便腾出空...
  • miao309410364
  • miao309410364
  • 2015-03-25 13:26
  • 3900
    我的新书
    个人资料
    • 访问:1918546次
    • 积分:16681
    • 等级:
    • 排名:第728名
    • 原创:191篇
    • 转载:52篇
    • 译文:0篇
    • 评论:1021条
    我的微博
    最新评论
    公众号
    百度统计