所谓人在家中坐锅从天上来。
项目里有个客服系统是接入的h5,最近收到反馈用户在客服系统输入时,输入框被Android弹起的软件盘遮挡,从而看不到输入框内容的问题。


正常界面
软键盘挡住

一开始想到的就是应该是没设置键盘自适应的属性,打开manifest找到相应的Activity,果然没有设置。不多说一顿操作猛如虎,设置

android:windowSoftInputMode="adjustResize"  

打开调试,如果你的当前Activity不是全屏模式,那么恭喜你,成功了。但是不幸的是我这个项目里Activity是全屏模式。结果还是被软键盘挡住。一脸懵逼~什么鬼。网上一搜,除了这个属性,全是让h5改属性的。把锅甩给h5?h5同学一脸懵逼,我这个客服模块在集团其他项目也用,该设置的position,fixed等属性都设置了,人家没报问题,你们自己想想办法。得,搞到最后锅还是回来了。那只能自己想办法了。。。
最终发现是设置Activity全屏模式引起的问题。要解决软件盘弹起遮挡问题,一版如下两种方式
(1)Native Activity非全屏模式下,要适应软键盘弹起一般可设置如下两种属性中的一种。

android:windowSoftInputMode="adjustResize|adjustSpan"  

有人说h5在这种模式下会失效。亲测adjustSpan确实是会在h5页面失效。

android:windowSoftInputMode="adjustSpan"  

(2)但是在h5全屏模式下以上两种方法都是失效的。这是Android系统目前存在的一个bug,编号5497。若需要在h5全屏模式下解决该问题,需要自己手动添加一个类,如下:

public class AndroidBug5497Workaround {    // For more information, see https://code.google.com/p/android/issues/detail?id=5497    // To use this class, simply invoke assistActivity() on an Activity that already has its content view set.    public static void assistActivity(Activity activity) {        new AndroidBug5497Workaround(activity);    }    private View mChildOfContent;    private int usableHeightPrevious;    private FrameLayout.LayoutParams frameLayoutParams;    private AndroidBug5497Workaround(Activity activity) {        //Decorview里分为title和content,content即是承载我们setContentView方法的布局的根布局        FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);        //mChildOfContent我们setContentView方法的布局        mChildOfContent = content.getChildAt(0);        //监听布局变化,任何界面变化都会触发该监听        //软键盘弹起同样也会触发该监听        mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {            public void onGlobalLayout() {                possiblyResizeChildOfContent();            }        });        frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams();    }    private void possiblyResizeChildOfContent() {        int usableHeightNow = computeUsableHeight();        if (usableHeightNow != usableHeightPrevious) {            int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();            //计算布局变化的高度            int heightDifference = usableHeightSansKeyboard - usableHeightNow;            if (heightDifference > (usableHeightSansKeyboard / 4)) {                // keyboard probably just became visible                //如果布局变化的高度大于全屏高度的4分之一,则认为可能是键盘弹出,需要改变我们setContentView的布局高度                frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;            } else {                // keyboard probably just became hidden                frameLayoutParams.height = usableHeightSansKeyboard;            }            //布局改变后重绘            mChildOfContent.requestLayout();            usableHeightPrevious = usableHeightNow;        }    }    //计算去掉键盘高度后的可用高度    private int computeUsableHeight() {        Rect r = new Rect();        mChildOfContent.getWindowVisibleDisplayFrame(r);        return (r.bottom - r.top);// 全屏模式下: return r.bottom//        return r.bottom;    }}
20180824233819.png

该类原理已添加在注释当中。
使用方式是引入该类后,在所需要设置的Activity oncreat()中添加如下一行代码

AndroidBug5497Workaround.assistActivity(this);

综上所述,解决软键盘弹起遮挡问题方法如下:

(1)Native页面:可设置adjustResize或adjustSpan属性。
(2)h5页面下:

  • h5非全屏模式,可设置adjustResize
  • h5全屏模式,可设置AndroidBug5497Workaround

参考资料:
https://code.google.com/p/android/issues/detail?id=5497
https://www.diycode.cc/topics/383

更多相关文章

  1. Android(安卓)LayoutInflater原理分析,带你一步步深入了解View(一
  2. 弹出输入法软键盘,编辑框悬浮,及覆盖遮挡问题的解决
  3. android学生管理系统,利用linerLayout,实现xml的读取和写入,以及按
  4. Android集成友盟QQ、空间分享、微信、微博闪退
  5. 切换tab的时候recyclerview滑动到最底部
  6. Android4.0 LCD和键盘 背光亮度设置
  7. android中anim动画效果
  8. animation1
  9. Android(安卓)Bugs——RecyclerView.Adapter java.lang.IllegalS

随机推荐

  1. Android的两种数据存储方式分析(一)
  2. Android获取View位置getHitRect、getDraw
  3. android学习博客
  4. Android中webview跟JAVASCRIPT中的交互
  5. [Android] ImageView.ScaleType设置图解
  6. 在Android上使用Http客户端的选择(译文)
  7. Android学习系列(40)--Android主题和样式
  8. Android学习之使用RadioGroup与RadioButt
  9. Android统计EditText的字母数字以及汉字
  10. Android(安卓)Camera2拍照(一)——使用Surf