Android是一个针对触摸屏专门设计的操作系统,当点击编辑框,系统自动为用户弹出软键盘,以便用户进行输入。

那么,弹出软键盘后必然会造成原有布局高度的减少,那么系统应该如何来处理布局的减少?我们能否在应用程序中进行自定义的控制?这些是本文要讨论的重点。

一、软键盘显示的原理

软件盘的本质是什么?软键盘其实是一个Dialog!

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

二、活动主窗口调整

android定义了一个属性,名字为windowSoftInputMode, 用它可以让程序可以控制活动主窗口调整的方式。我们可以在AndroidManifet.xml中对Activity进行设置。如:android:windowSoftInputMode="stateUnchanged|adjustPan"

该属性可选的值有两部分,一部分为软键盘的状态控制,另一部分是活动主窗口的调整。前一部分本文不做讨论,请读者自行查阅android文档。

模式一,压缩模式

windowSoftInputMode的值如果设置为adjustResize,那么该Activity主窗口总是被调整大小以便留出软键盘的空间。

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

重写Layout布局:

1.publicclassResizeLayoutextendsLinearLayout{

2.privatestaticintcount =0;

3.

4.publicResizeLayout(Context context, AttributeSet attrs) {

5.super(context, attrs);

6.     }

7.

8.@Override

9.protectedvoidonSizeChanged(intw,inth,intoldw,intoldh) {

10.super.onSizeChanged(w, h, oldw, oldh);

11.

12.         Log.e("onSizeChanged "+ count++,"=>onResize called! w="+w +",h="+h+",oldw="+oldw+",oldh="+oldh);

13.     }

14.

15.@Override

16.protectedvoidonLayout(booleanchanged,intl,intt,intr,intb) {

17.super.onLayout(changed, l, t, r, b);

18.         Log.e("onLayout "+ count++,"=>OnLayout called! l="+ l +", t="+ t +",r="+ r +",b="+b);

19.     }

20.

21.@Override

22.protectedvoidonMeasure(intwidthMeasureSpec,intheightMeasureSpec) {

23.super.onMeasure(widthMeasureSpec, heightMeasureSpec);

24.

25.         Log.e("onMeasure "+ count++,"=>onMeasure called! widthMeasureSpec="+ widthMeasureSpec +", heightMeasureSpec="+ heightMeasureSpec);

26.     }1. public class ResizeLayout extends LinearLayout{

2. private static int count = 0;

3.

4. public ResizeLayout(Context context, AttributeSet attrs) {

5. super(context, attrs);

6. }

7.

8. @Override

9. protected void onSizeChanged(int w, int h, int oldw, int oldh) {

10. super.onSizeChanged(w, h, oldw, oldh);

11.

12. Log.e("onSizeChanged " + count++, "=>onResize called! w="+w + ",h="+h+",oldw="+oldw+",oldh="+oldh);

13. }

14.

15. @Override

16. protected void onLayout(boolean changed, int l, int t, int r, int b) {

17. super.onLayout(changed, l, t, r, b);

18. Log.e("onLayout " + count++, "=>OnLayout called! l=" + l + ", t=" + t + ",r=" + r + ",b="+b);

19. }

20.

21. @Override

22. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

23. super.onMeasure(widthMeasureSpec, heightMeasureSpec);

24.

25. Log.e("onMeasure " + count++, "=>onMeasure called! widthMeasureSpec=" + widthMeasureSpec + ", heightMeasureSpec=" + heightMeasureSpec);

26. }

我们的布局设置为:

1.

2.xmlns:android="http://schemas.android.com/apk/res/android"

3.android:id="@+id/root_layout"

4.android:layout_width="fill_parent"

5.android:layout_height="fill_parent"

6.android:orientation="vertical"

7.>

8.

9.

10.android:layout_width="fill_parent"

11.android:layout_height="wrap_content"

12./>

13.

14.

15.android:id="@+id/bottom_layout"

16.android:layout_width="fill_parent"

17.android:layout_height="fill_parent"

18.android:orientation="vertical"

19.android:gravity="bottom">s

20.

21.

22.android:layout_width="fill_parent"

23.android:layout_height="wrap_content"

24.android:text="@string/hello"

25.android:background="#77777777"

26./>

27.

28.

1.

2. xmlns:android="http://schemas.android.com/apk/res/android"

3. android:id="@+id/root_layout"

4. android:layout_width="fill_parent"

5. android:layout_height="fill_parent"

6. android:orientation="vertical"

7. >

8.

9.

10. android:layout_width="fill_parent"

11. android:layout_height="wrap_content"

12. />

13.

14.

15. android:id="@+id/bottom_layout"

16. android:layout_width="fill_parent"

17. android:layout_height="fill_parent"

18. android:orientation="vertical"

19. android:gravity="bottom">s

20.

21.

22. android:layout_width="fill_parent"

23. android:layout_height="wrap_content"

24. android:text="@string/hello"

25. android:background="#77777777"

26. />

27.

28.

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。

实际上,当设置为adjustResize后,软键盘弹出时,要对主窗口布局重新进行measure和layout,而在layout时,发现窗口的大小发生的变化,因此调用了onSizeChanged。

从下图的运行结果我们也可以看出,原本在下方的TextView被顶到了输入法的上方。

模式二,平移模式

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并没有调用,这说明输入法弹出前后并没有改变原有布局的大小。

从下图的运行结果我们可以看到,下方的TextView并没有被顶到输入法上方。

事实上,当输入框不会被遮挡时,该模式没有对布局进行调整,然而当输入框将要被遮挡时,窗口就会进行平移。也就是说,该模式始终是保持输入框为可见。如下图,整个窗口,包括标题栏均被上移,以保证文本框可见。

模式三 自动模式

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

也就是说,系统自动决定是采用平移模式还是压缩模式,决定因素在于内容是否可以滚动。

三、侦听软键盘的显示隐藏

有时候,借助系统本身的机制来实现主窗口的调整并非我们想要的结果,我们可能希望在软键盘显示隐藏的时候,手动的对布局进行修改,以便使软键盘弹出时更加美观。这时就需要对软键盘的显示隐藏进行侦听。

直接对软键盘的显示隐藏侦听的方法本人没有找到,如果哪位找到的方法请务必告诉本人一声。还有本方法针对压缩模式,平移模式不一定有效。

我们可以借助软键盘显示和隐藏时,对主窗口进行了重新布局这个特性来进行侦听。如果我们设置的模式为压缩模式,那么我们可以对布局的onSizeChanged函数进行跟踪,如果为平移模式,那么该函数可能不会被调用。

我们可以重写根布局,因为根布局的高度一般情况下是不发生变化的。

假设跟布局为线性布局,模式为压缩模式,我们写一个例子,当输入法弹出时隐藏某个view,输入法隐藏时显示某个view。

1.publicclassResizeLayoutextendsLinearLayout{

2.privateOnResizeListener mListener;

3.

4.publicinterfaceOnResizeListener {

5.voidOnResize(intw,inth,intoldw,intoldh);

6.     }

7.

8.publicvoidsetOnResizeListener(OnResizeListener l) {

9.         mListener = l;

10.     }

11.

12.publicResizeLayout(Context context, AttributeSet attrs) {

13.super(context, attrs);

14.     }

15.

16.@Override

17.protectedvoidonSizeChanged(intw,inth,intoldw,intoldh) {

18.super.onSizeChanged(w, h, oldw, oldh);

19.

20.if(mListener !=null) {

21.             mListener.OnResize(w, h, oldw, oldh);

22.         }

23.     }

24. }

1. public class ResizeLayout extends LinearLayout{

2. private OnResizeListener mListener;

3.

4. public interface OnResizeListener {

5. void OnResize(int w, int h, int oldw, int oldh);

6. }

7.

8. public void setOnResizeListener(OnResizeListener l) {

9. mListener = l;

10. }

11.

12. public ResizeLayout(Context context, AttributeSet attrs) {

13. super(context, attrs);

14. }

15.

16. @Override

17. protected void onSizeChanged(int w, int h, int oldw, int oldh) {

18. super.onSizeChanged(w, h, oldw, oldh);

19.

20. if (mListener != null) {

21. mListener.OnResize(w, h, oldw, oldh);

22. }

23. }

24. }

在我们的Activity中,通过如下方法调用:

1.publicclassInputMethodTestActivityextendsActivity {

2.privatestaticfinalintBIGGER =1;

3.privatestaticfinalintSMALLER =2;

4.privatestaticfinalintMSG_RESIZE =1;

5.

6.privatestaticfinalintHEIGHT_THREADHOLD =30;

7.

8.classInputHandlerextendsHandler {

9.@Override

10.publicvoidhandleMessage(Message msg) {

11.switch(msg.what) {

12.caseMSG_RESIZE: {

13.if(msg.arg1 == BIGGER) {

14.                     findViewById(R.id.bottom_layout).setVisibility(View.VISIBLE);

15.                 }else{

16.                     findViewById(R.id.bottom_layout).setVisibility(View.GONE);

17.                 }

18.             }

19.break;

20.

21.default:

22.break;

23.             }

24.super.handleMessage(msg);

25.         }

26.     }

27.

28.privateInputHandler mHandler =newInputHandler();

29.

30./** Called when the activity is first created. */

31.@Override

32.publicvoidonCreate(Bundle savedInstanceState) {

33.super.onCreate(savedInstanceState);

34.         setContentView(R.layout.main);

35.

36.         ResizeLayout layout = (ResizeLayout) findViewById(R.id.root_layout);

37.         layout.setOnResizeListener(newResizeLayout.OnResizeListener() {

38.

39.publicvoidOnResize(intw,inth,intoldw,intoldh) {

40.intchange = BIGGER;

41.if(h

42.                     change = SMALLER;

43.                 }

44.

45.                 Message msg =newMessage();

46.                 msg.what =1;

47.                 msg.arg1 = change;

48.                 mHandler.sendMessage(msg);

49.             }

50.         });

51.     }

52. }

1. public class InputMethodTestActivity extends Activity {

2. private static final int BIGGER = 1;

3. private static final int SMALLER = 2;

4. private static final int MSG_RESIZE = 1;

5.

6. private static final int HEIGHT_THREADHOLD = 30;

7.

8. class InputHandler extends Handler {

9. @Override

10. public void handleMessage(Message msg) {

11. switch (msg.what) {

12. case MSG_RESIZE: {

13. if (msg.arg1 == BIGGER) {

14. findViewById(R.id.bottom_layout).setVisibility(View.VISIBLE);

15. } else {

16. findViewById(R.id.bottom_layout).setVisibility(View.GONE);

17. }

18. }

19. break;

20.

21. default:

22. break;

23. }

24. super.handleMessage(msg);

25. }

26. }

27.

28. private InputHandler mHandler = new InputHandler();

29.

30. /** Called when the activity is first created. */

31. @Override

32. public void onCreate(Bundle savedInstanceState) {

33. super.onCreate(savedInstanceState);

34. setContentView(R.layout.main);

35.

36. ResizeLayout layout = (ResizeLayout) findViewById(R.id.root_layout);

37. layout.setOnResizeListener(new ResizeLayout.OnResizeListener() {

38.

39. public void OnResize(int w, int h, int oldw, int oldh) {

40. int change = BIGGER;

41. if (h < oldh) {

42. change = SMALLER;

43. }

44.

45. Message msg = new Message();

46. msg.what = 1;

47. msg.arg1 = change;

48. mHandler.sendMessage(msg);

49. }

50. });

51. }

52. }

这里特别需要注意的是,不能直接在OnResizeListener中对要改变的View进行更改,因为OnSizeChanged函数实际上是运行在View的layout方法中,如果直接在onSizeChange中改变view的显示属性,那么很可能需要重新调用layout方法才能显示正确。然而我们的方法又是在layout中调用的,因此会出现错误。因此我们在例子中采用了Handler的方法。

android输入法隐藏状态栏,android 输入法设置显示隐藏相关推荐

  1. Eclipse自定义设置显示隐藏工具栏toolbar

    Eclipse通过此方法可以自定义设置显示隐藏工具栏toolbar. 具体案例如下: 在Java Perspective界面解决消失的debug工具栏: 打开Window ->Customize ...

  2. 如何隐藏CAD图层?怎么显示隐藏的CAD图层?

    CAD图层是编辑CAD文件时常常会使用的工具,如果我们在编辑CAD文件时,想要将一些不重要的图层隐藏,或者将隐藏的图层显示,那么应该怎么进行操作?如何隐藏CAD图层?怎么显示隐藏的CAD图层?接下来我 ...

  3. Android布局延伸状态栏,Android沉浸式全屏讲解(状态栏、导航栏处理)

    Android应用中经常会有一些要求全屏显隐状态栏导航栏的需求.通过全屏沉浸式的处理可以让应用达到更好的显示效果.下面系统的讲解一下有关全屏,隐藏状态栏导航栏,沉浸式的知识. 在Android4.1之 ...

  4. html密码框输入内容隐藏,jQuery输入框密码的显示隐藏【代码分享】

    效果图: 代码如下: jQuery输入框密码显示隐藏代码 @font-face {font-family: "iconfont"; src: url('iconfont.eot') ...

  5. html查看更多隐藏内容,jQuery点击显示隐藏更多文字内容插件jquery.morecontent.js

    插件描述:这是一款jQuery显示隐藏更多文字内容插件.该插件可以将很长的一段文字按要求进行部分隐藏和全部展示,并且可以定制隐藏和展开内容时的动画效果. jquery.morecontent.js 这 ...

  6. elementui 隐藏输入框_vue+element-ui实现显示隐藏密码

    最终实现效果 显示隐藏密码.gif 实现思路(第一种方法) 因为输入框本身没有切换明文与暗文的功能,所以我们要实现切换功能就需要两个输入框,通过JS来控制样式dispaly:none来指定谁被渲染出来 ...

  7. 隐藏html文本节点,javascript-D3-仅显示/隐藏单击节点的文本

    我试图单击显示/隐藏D3中节点的文本.我尝试使用以下代码: var node = svg.selectAll(".node") .data(json.nodes) (...) no ...

  8. html5密码隐藏,Bootstrap实现用户输入密码显示隐藏代码

    Bootstrap实现用户输入密码显示隐藏代码 js代码 $(function() { $('#password').password().on('show.bs.password', functio ...

  9. css中显示隐藏div层,JS CSS 显示隐藏DIV 层

    匿名用户 1级 2011-01-12 回答 调整了下标签的位置 一般js要放在css后面 最好js放在dom最后,等待dom解释完毕再执行js代码 无标题文档 #div1{ border:1px #0 ...

最新文章

  1. 使用opencv_traincascade训练Haar、HOG、LBP Adaboost分类器
  2. 2.1 Java程序的构成
  3. java重载_Java的重载与覆盖,傻傻分不清!
  4. linux shell rman删除归档_我们一起学一学渗透测试——黑客应该掌握的Linux基础
  5. c语言奇数正偶数负,C语言二级考试练习题循环控制结构(二)
  6. python引入导入自定义模块和外部文件
  7. android 库编译报错,Android Studio编译项目报错
  8. python爬虫案例-乌托家家具公司数据爬取
  9. AD数据库备份[为企业部署Windows Server 2008系列十五]
  10. CodeReview 常见代码问题( 下 )
  11. Python 三级菜单-字符编码和转码-集合的操作-文件的操作
  12. 神奇的mysql查询
  13. 职场 软件实施工程师的地位以及发展前景
  14. python自回归_自回归模型(AR )
  15. 浏览器插件:插件推荐
  16. CentOs下安装pip3
  17. 关于个人网贷查询系统网贷信用查询,公司开发图片整合技术
  18. OpenCV图像处理_2:平滑smoothing模糊blurring操作
  19. 装机必备android东西nbsp;有你需…
  20. 02-K3S 架构及快速入门

热门文章

  1. PHP编写rss源(续)
  2. android 打开系统键盘的方法
  3. excel快速删除空行
  4. iPhone手机史上最全的扫盲帖【解锁,激活,Cydia,基带,裸机】
  5. peel在Linux生成excel,zplane -
  6. Java身份证号校验
  7. 手机计算机软件删除了怎么恢复,电脑的程序软件不小心被删掉,该如何恢复?...
  8. 区块链共识协议最详细的分析
  9. C# Basler相机采集图像
  10. 微信小程序开发基础教程