在Android开发中,经常会遇到键盘挡住输入框的情况,比如登录界面或注册界面,弹出的软键盘把登录或注册按钮挡住了,用户必须把软键盘收起,才能点击相应按钮,这样的用户体验非常不好。像微信则直接把登录按钮做在输入框的上面,但有很多情况下,这经常满足不了需求。同时如果输入框特别多的情况下,点击输入时,当前输入框没被挡住,但是当前输入框下面的输入框却无法获取焦点,必须先把键盘收起,再去获取下面输入框焦点,这样用户体验也非常不好,那有什么办法呢?
下面对几种在开发中常用的方法进行总结:
方法一:windowSoftInputMode:adjustResize|adjustPan
主要实现方法:
在AndroidManifest.xml对应的Activity里添加
Android:windowSoftInputMode=”adjustPan”或是android:windowSoftInputMode=”adjustResize”属性
但使用这两种属性,我们可以总结以下几点:
1) 使用adjustPan, 如果需要输入的项比较多时,点击输入框,当前输入项会被顶到软键盘上方,但若当前输入框下面还有输入项时,却需要先收起键盘,再点击相应的输入项才能输入。这样操作太繁琐了,对于用户体验不大好;
2) adjustResize的使用,需要界面本身可显示的窗口内容能调整,如果不能,不起作用;
方法二:在界面最外层布局包裹ScrollView
1、只使用ScrollView
在相应界面的xml布局中,最外层添加一个ScrollView,不在AndroidMainfest.xml中设置任何android:windowSoftInputMode属性,此时点击输入框,输入框均不会被软键盘档住。即使当前输入框下方也有输入框,在键盘显示的情况下,也可以通过上下滑动界面来输入,而不用先隐藏键盘,点击下方输入框,再显示键盘输入。
2、ScrollView+adjustPan
我们再在该类的AndroidMainfest.xml中设置windowSoftInputMode属性为adjustPan
方法三:当键盘弹起时,让界面整体上移;键盘收起,让界面整体下移
使用场景:针对界面全屏或是沉浸式状态栏,输入框不会被键盘遮挡。主要用于一些登录界面,或是需要把界面整体都顶上去的场景。
方法四:监听Activity顶层View,判断软键盘是否弹起,对界面重新绘制
此方法的实现来自android中提出的issue 5497 https://code.google.com/p/android/issues/detail?id=5497
使用场景:针对界面全屏或是沉浸式状态栏,界面包含比较多输入框,界面即使包裹了一层ScrollView,在键盘显示时,当前输入框下面的输入不能通过上下滑动界面来输入。
总结:
下面对上面几种方法进行对比:
方法一:优点:使用简单,只需在Activity的AndroidMainfest.xml中设置windowSoftInput属性即可。
注意点:adjustResize属性必须要界面大小可以自身改变;
缺点:当输入框比较多时,当前输入框下方的输入框会初键盘挡住,须收起键盘再进入输入;使用adjustPan,输入框较多时,因它是把界面当成一个整体,只会显示一屏的高度,会把ActionBar顶上去。
方法二:优点:使用简单,只需在Activity的最外层布局包裹一个ScrollView即可。
注意点:不可使用adjustPan属性,否则ScrollView失效;
缺点:对于全屏时,在键盘显示时,无法上下滑动界面达到输入的目的;
方法三:优点:可以解决全屏时,键盘挡入按钮问题。
缺点:只要有此需求的Activity均需要获取到最外层控件和最后一个控件,监测键盘是否弹出,再调用控件的scrollTo方法对界面整体上移或是下移。代码冗余。
方法四:优点:可以解决全屏时,键盘挡入输入框问题。只需要写一个全局类,其他有需求的界面直接在onCreate方法里调用此类的全局方法,即可。
缺点:多用了一个类。
综上所述:
1) 当输入框比较少时,界面只有一个输入框时,可以通过方法一设置adjustPan;
2) 如果对于非全屏/非沉浸式状态栏需求,只需要使用方法二即可;
3) 如果全屏全屏/沉浸式状态栏界面只有一个类有键盘挡入输入框需求,可使用方法三;
4) 如果大部分界面均使用全屏或沉浸式状态栏,且有此需求,则选择方法四更恰当。