一、背景介绍
      首先介绍关于adjustSize与adjustpan

        在manifest文件设置activity的windowSoftInputMode设置为 adjustPan 或者adjustResize

       adjustPan会在软键盘弹出的时候平推整个界面,整个界面的大小不变的。缺点: 你编辑的部分会上弹到软键盘上面,但是会造成不可以拖拉,如果编辑的内容下面还有view,你想要操作的话必须先关闭软键盘

      adjustResize则是会调整大小,以便为屏幕上的软键盘腾出空间。但是在全屏/沉浸式状态栏模式下是不可用的

二、解决方式
        安卓提供的adjustResize在全屏模式下不可用,就只能采用其他方式,谷歌上的大神采取的方式是根据app可展示区域的大小动态更改内容的大小,用scrollview包裹住content,这样就可以自己滑动做到不遮挡】

        tips:  根目录必须用ScrollView包裹,不然展示区域变小后无法滑动,相当于没用   另外处理滑动冲突可以采用nestScrollView

       这个代码考虑到了以下几种情况:

        ①有实体底部导航按钮的(oppo r9)  ②没有实体按钮但是开启虚拟底部导航按钮  (三星s8)  ③没有实体按钮但是关闭虚拟底部导航按钮的(红米k30)   ④三的基础上,但是代码运行却反馈有虚拟按钮的(oppo findx)

        (其实难度主要在于如何判断得出底部导航按钮的高度和有无,需要对三星特别处理)

        直接上代码:

   

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;
     Activity activity;
  
     private AndroidBug5497Workaround(Activity activity) {
         this.activity =activity;
         FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);
         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
                 frameLayoutParams.height = usableHeightSansKeyboard - heightDifference+ getStatusBarHeight();
             } else {
                 // keyboard probably just became hidden
                 frameLayoutParams.height = usableHeightSansKeyboard-getNavigationBarHeight();
             }
             mChildOfContent.setBottom(frameLayoutParams.height);
             mChildOfContent.requestLayout();
             usableHeightPrevious = usableHeightNow;
         }
     }
  
     private int computeUsableHeight() {
         Rect r = new Rect();
         mChildOfContent.getWindowVisibleDisplayFrame(r);
         return (r.bottom - r.top);
     }
  
  
     public int getStatusBarHeight(){
         int result = 0;
         int resourceId = ContextUtils.getApplicationContext().getResources().getIdentifier("status_bar_height", "dimen", "android");
         if (resourceId > 0) {
             result = ContextUtils.getApplicationContext().getResources().getDimensionPixelSize(resourceId);
         }
         return result;
     }
  
  
     /**
      * 获取底部虚拟导航栏的高度
      * @return
      */
     public  int getNavigationBarHeight() {
         int height = 0;
         //屏幕实际尺寸
         DisplayMetrics dm = new DisplayMetrics();
         activity.getWindowManager().getDefaultDisplay().getRealMetrics(dm);
         int phoneHeight = dm.heightPixels;
         if (isNavigationBarExist()) {
             Resources resources =activity.getResources();
             int resourceId = resources.getIdentifier("navigation_bar_height",
                     "dimen", "android");
             if (resourceId > 0) {
                 //获取NavigationBar的高度
                 height = resources.getDimensionPixelSize(resourceId);
             }
         }
         if (height > 0){
             //处理全屏模式下,部分手机isNavigationBarExist()始终返回true,NavigationBar的高度
             int diffValue = (DensityUtils.getScreenHeight(ContextUtils.getApplicationContext()) + height) - phoneHeight;
              //这里对三星特别处理,以为三星机会把状态栏高度算入真正显示高度,
              //不过也可以理解,毕竟我们是全屏模式
             if(!"SAMSUNG".equalsIgnoreCase(Build.MANUFACTURER)){
                 diffValue+= getStatusBarHeight();
             }
             if (diffValue > 0){
                 height -= diffValue;
             }
         }
         return height;
     }
  
     /**
      * 检测底部虚拟导航栏是否存在
      *有很多教程写通过读取系统参数,无效,因为有些有参数但是不展示
      * @return
      */
     public  boolean isNavigationBarExist(){
         ViewGroup vp = (ViewGroup) activity.getWindow().getDecorView();
         if (vp != null) {
             for (int i = 0; i < vp.getChildCount(); i++) {
                 vp.getChildAt(i).getContext().getPackageName();
                 if (vp.getChildAt(i).getId() != View.NO_ID
                         && "navigationBarBackground".equals(activity.getResources().getResourceEntryName(vp.getChildAt(i).getId()))) {
                     return true;
                 }
             }
         }
         return false;
     }
 }


使用方式:   

AndroidBug5497Workaround.assistActivity(你的activity)