最近在调试App过程遇到软件盘遮挡EditText的问题,特记录下问题的解决过程
在4.4版本上,如果EditText设置了gravity=“center|right”其中之一且同时设置android:windowSoftInputMode="stateHidden|adjustPan",就会导致屏幕底部的EditText连续点击弹出键盘时,从第二次开会一直遮挡住EditText。在5.0+版本上不存在该问题,这可能是早期版本的Bug。

输入法的行为还与状态栏的状态有关联,比如说沉浸式、全屏及是否透明。

正常情况下,系统UI会占用app一些空间,例如状态栏、键盘、导航栏等,也就是说我们的app UI不会出现在系统UI之下,但从测试结果来看,为了占用状态栏空间或全屏,设置了上面的一些属性后,就会被系统UI覆盖。

为了规避不同系统版本以及系统状态差异造成的软件盘遮挡控件问题,需要一种统一的解决思路。这里给出一种思路:将UI界面设置为adjustPan, 通过监测输入法的弹出及隐藏来动态调整UI 的rootView的位置,如果输入法弹出时,焦点View(一般是EditText)在输入法上方显示,那么不做处理,如果输入法弹出时,焦点View被输入法遮挡,那么就rootView向上滚动,使输入框正好在输入法上方显示。

具体实现步骤如下:

  1. 定义并实现SoftKeyboardManager管理类,用于监听SoftKeyboard的弹出与隐藏状态,并通过接口方法通知出去。
    界面UI状态的变化通过ViewTreeObserver.OnGlobalLayoutListener接口来监听
public class SoftKeyboardManager  implements ViewTreeObserver.OnGlobalLayoutListener{public static final boolean DEBUG = false;public interface SoftKeyboardStateListener {void onSoftKeyboardOpened(int keyboardHeightInPx);void onSoftKeyboardClosed();}private final List<SoftKeyboardStateListener> listeners = new LinkedList<SoftKeyboardStateListener>();private final View activityRootView;private int lastSoftKeyboardHeightInPx;private boolean isSoftKeyboardOpened;public SoftKeyboardManager(View activityRootView) {this(activityRootView, false);}public SoftKeyboardManager(View activityRootView, boolean isSoftKeyboardOpened) {this.activityRootView = activityRootView;this.isSoftKeyboardOpened = isSoftKeyboardOpened;activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(this);}@Overridepublic void onGlobalLayout() {final Rect r = new Rect();//r will be populated with the coordinates of your view that area still visible.activityRootView.getWindowVisibleDisplayFrame(r);final int heightDiff = activityRootView.getRootView().getHeight() - (r.bottom - r.top);if (DEBUG){Log.d("SoftKeyboardStateHelper", "heightDiff:" + heightDiff);}if (!isSoftKeyboardOpened && heightDiff > 500) { // if more than 100 pixels, its probably a keyboard...isSoftKeyboardOpened = true;notifyOnSoftKeyboardOpened(heightDiff);//if (isSoftKeyboardOpened && heightDiff < 100)} else if (isSoftKeyboardOpened && heightDiff < 500) {isSoftKeyboardOpened = false;notifyOnSoftKeyboardClosed();}}public void setIsSoftKeyboardOpened(boolean isSoftKeyboardOpened) {this.isSoftKeyboardOpened = isSoftKeyboardOpened;}public boolean isSoftKeyboardOpened() {return isSoftKeyboardOpened;}/*** Default value is zero (0)** @return last saved keyboard height in px*/public int getLastSoftKeyboardHeightInPx() {return lastSoftKeyboardHeightInPx;}public void addSoftKeyboardStateListener(SoftKeyboardStateListener listener) {listeners.add(listener);}public void removeSoftKeyboardStateListener(SoftKeyboardStateListener listener) {listeners.remove(listener);}public void dispose(){activityRootView.getViewTreeObserver().removeOnGlobalLayoutListener(this);}private void notifyOnSoftKeyboardOpened(int keyboardHeightInPx) {this.lastSoftKeyboardHeightInPx = keyboardHeightInPx;for (SoftKeyboardStateListener listener : listeners) {if (listener != null) {listener.onSoftKeyboardOpened(keyboardHeightInPx);}}}private void notifyOnSoftKeyboardClosed() {for (SoftKeyboardStateListener listener : listeners) {if (listener != null) {listener.onSoftKeyboardClosed();}}}
}
  1. 在主界面Activity或者Fragment中注册监听并做rootView的平移出来。
public class BaseFrameActivity extends FragmentActivity implements SoftKeyboardManager.SoftKeyboardStateListener{private SoftKeyboardManager softKeyboardManager;
protected LinearLayout rootLl;
@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);super.setContentView(R.layout.root_container);rootLl = (LinearLayout)findViewById(R.id.root_rl);softKeyboardManager = new SoftKeyboardManager(rootLl);softKeyboardManager.addSoftKeyboardStateListener(this);......}@Overrideprotected void onDestroy() {super.onDestroy();softKeyboardManager.removeSoftKeyboardStateListener(this);softKeyboardManager.dispose();}@Overridepublic void onSoftKeyboardOpened(int keyboardHeightInPx) {if (SoftKeyboardManager.DEBUG){Log.d(TAG, "keyboardOpened, keyboardHeightInPx = "+keyboardHeightInPx);}Rect rect = new Rect();//获取root在窗体的可视区域rootLl.getWindowVisibleDisplayFrame(rect);//获取root在窗体的不可视区域高度(被其他View遮挡的区域高度)int rootInvisibleHeight = rootLl.getRootView().getHeight() - rect.bottom;//若不可视区域高度大于100,则键盘显示if (rootInvisibleHeight > 100) {int[] location = new int[2];//获取focusedView在窗体的坐标View focusedView = getCurrentFocus();if (focusedView instanceof EditText){focusedView.getLocationInWindow(location);int focusedViewPosY = location[1] + focusedView.getHeight();if (SoftKeyboardManager.DEBUG){Log.d(TAG, "rect.bottom= "+rect.bottom+", focusedViewPosY = "+focusedViewPosY);Log.i(TAG, "focused view need scroll up or down");}int srollHeight = focusedViewPosY - rect.bottom;if (SoftKeyboardManager.DEBUG){Log.i(TAG, "srollHeight = "+srollHeight);}if (srollHeight>0) {//焦点被输入法遮挡,View向上滚动rootLl.scrollTo(0, srollHeight);}}}}@Overridepublic void onSoftKeyboardClosed() {if (SoftKeyboardManager.DEBUG){Log.d(TAG, "keyboardClosed ");}//输入法退出,root滚动到初始位置rootLl.scrollTo(0, 0);}
}

参考文献

softInputMode设置成adjustPan,键盘第二次弹出时会遮挡输入框
键盘弹起引起的Pannel布局发送变化问题解决
Android 软键盘的全面解析,让你不再怕控件被遮盖!

Android软键盘遮挡EditText问题相关推荐

  1. Android软键盘遮挡的四种解决方案

    Android软键盘遮挡的四种解决方案 参考文章: (1)Android软键盘遮挡的四种解决方案 (2)https://www.cnblogs.com/jerehedu/p/4194125.html ...

  2. android自定义键盘遮挡,Android软键盘遮挡的四种完美解决方案

    一.问题概述 在编辑框输入内容时会弹出软键盘,而手机屏幕区域有限往往会遮住输入界面,我们先看一下问题效果图: 输入用户名和密码时,系统会弹出键盘,造成系统键盘会挡住文本框的问题,如图所示: 输入密码时 ...

  3. android 软键盘遮挡登陆按钮的问题,Android优雅的方式解决软键盘遮挡按钮问题

    前言 比如在进行登录的操作中,用户输入完密码之后,肯定是想直接点击登录按钮的.返回键隐藏软键盘这样的体验肯定很糟糕,程序员,遇到问题解决问题. 实现1 xml android:id="@+i ...

  4. android 键盘遮挡,Android软键盘遮挡的四种解决方案

    在编辑框输入内容时会弹出软键盘,而手机屏幕区域有限往往会遮住输入界面,我们先看一下问题效果图: 输入用户名和密码时,系统会弹出键盘,造成系统键盘会挡住文本框的问题,如图所示: 输入密码时输入框被系统键 ...

  5. Android虚拟键盘遮挡EditText的解决方案

    在做项目的时候,遇到的问题,就是点击编辑框软键盘会把编辑框给遮挡住,于是网上查资料说只需要在注册文件里的当前Activity配置上: <activity android:windowSoftIn ...

  6. rn android软键盘遮挡布局处理,完美解决RN 键盘遮挡问题

    当输入框在底部的时候, 唤起键盘会造成遮挡问题,解决方法如下: class ForumDetail extends React.Component { render(){ let behavior = ...

  7. android EditText光标位置,光标样式,EditText限制输入内容,软键盘遮挡的EditText,搜索框,限制输入表情

    显示在软键盘上 android:windowSoftInputMode="adjustPan|stateHidden" 1.光标位置 homesosoedit.setSelecti ...

  8. Android软键盘隐藏,遮挡EidtText解决办法

    一.自动弹出软键盘 Timer timer=new Timer(); timer.schedule(new TimerTask() { public void run() { InputMethodM ...

  9. android 软键盘遮住按钮,Android应用中出现软键盘遮挡住按钮如何解决

    Android应用中出现软键盘遮挡住按钮如何解决 发布时间:2020-11-20 16:25:47 来源:亿速云 阅读:110 作者:Leah Android应用中出现软键盘遮挡住按钮如何解决?相信很 ...

最新文章

  1. “完美论文”过于真实,道出了科研狗的痛
  2. .NET Core R2安装教程及Hello示例
  3. mysql连接查询之间的差异性
  4. 速学c++(3)-函数
  5. f1 score 代码_腾讯广告算法大赛冠军代码解读:稠密特征工程
  6. 计算机组成原理AB什么运算,计算机组成原理运算器实验.doc
  7. HTML5炫彩舞蹈学院官网网站模板
  8. Java程序员最厉害的是什么,「解密」谁是世界上最好的java程序员?
  9. 严重抗议:被砍了个尾巴
  10. 编程修养 from匠人的百宝箱
  11. 福昕pdf阅读器 去广告版|福昕pdf阅读器Foxit reader 去广告电脑版下载v9.3
  12. Java定时任务表达式
  13. TPC_mcgs打印方案
  14. js 禁止鼠标菜单键及键盘快捷键
  15. 机器视觉工程师之关于程序员的头发
  16. 如何使用商品历史价格查询网站
  17. ycf 梗_抖音三个汤勺放在筷子上是什么梗 抖音三个汤勺放在筷子上出处介绍[多图]...
  18. 【MC 网易-我的世界-mod开发基础笔记】 --- 常用的在线工具
  19. github出现HTTP request failed
  20. Django实现QQ登录

热门文章

  1. 2020常州市程序设计小能手真题及题解
  2. 在线购物系统设计类图
  3. 判断tableViewCell是否在可视区
  4. luogu P2221 [HAOI2012]高速公路
  5. 【考研线代】一. 行列式
  6. C# 淘宝数据包下载,生成csv格式。可直接通过淘宝助理上传到淘宝店铺
  7. 电脑硬盘锁怎么解除linux,开机硬盘锁怎么解除,电脑硬盘锁忘记密码-
  8. 记:《洛克菲勒留给儿子的38封信》-- 1
  9. 借势如泳装,尤爱三点式
  10. ACM模式各种输入整理(C++)