软键盘和editext 的深坑

2,189 阅读1分钟

android:windowSoftInputMode的值adjustPan或者adjustResize 有时候有效,有时候失效,原来的官方的锅,万恶的适配:

原因: www.jianshu.com/p/306482e17…

有虚拟键盘的话,会有问题,建议用我的

activity 解决方案:

  • onCreate()中调用:

      new KeyboardPatch(this,findViewById(android.R.id.content)).enable();
    
  • onDestroy()中调用:

      keyboard.disable();
    
  • 代码

      /   **
      * @author DrChen
      * @Date 2019/12/13 0013.
      * qq:1414355045
        */   
          public class KeyboardPatch {
    
          private Activity activity;
          private View decorview;
          private View contentview;
          /** 
           *   构造函数
         * @param act 需要解决bug的activity
         * @param contentview 界面容器,activity中一般是 findViewById(android.R.id.content)  ,也可能是fragment的容器,根据个人需要传递
         * */
      public KeyboardPatch(Activity act, View contentview)
         {
          this.activity = act;
            this.decorview = act.getWindow().getDecorView();
          this.contentview = contentview;
      }
       /**
       * 监听layout变化
       * */
         public void enable()
      {
          activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
          if (Build.VERSION.SDK_INT >= 19)
          {
              decorview.getViewTreeObserver().addOnGlobalLayoutListener(ongloballayoutlistener);
          }
      }
      /**
       * 取消监听
       * */
      public void disable()
      {
          activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
          if (Build.VERSION.SDK_INT >= 19)
          {
              decorview.getViewTreeObserver().removeOnGlobalLayoutListener(ongloballayoutlistener);
          }
      }
      private ViewTreeObserver.OnGlobalLayoutListener ongloballayoutlistener = new ViewTreeObserver.OnGlobalLayoutListener()
      {
    
    
          @Override
          public void onGlobalLayout()
          {
              Rect r = new Rect();
              decorview.getWindowVisibleDisplayFrame(r);
              int height = decorview.getContext().getResources().getDisplayMetrics().heightPixels;
              int diff = height - r.bottom;
              if (diff != 0)
              {
                  if (contentview.getPaddingBottom() != diff)
                  {
                      contentview.setPadding(0, 0, 0, diff);
                  }
              }
              else
              {
                  if (contentview.getPaddingBottom() != 0)
                  {
                      contentview.setPadding(0, 0, 0, 0);
                  }
              }
          }
      };
    
     }
    

dialog 解决方案:

    getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);

按理说下面方案,可以让dialog 实现这种效果:

但是实际是软键盘遮盖了弹窗和输入框
其实是你的全屏和透明状态栏的问题,官方挖的坑

但是dialog不能用activity的方法计算高度要搞一些东西,只能对dialog 的主题模式一通改造,如下

     //dialog 初始化时直接清理掉影响操作的主题(google的坑)
     getDialog().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN| WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
    //设置一个不是全屏的主题
    getDialog(). getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
    //设置软键的盘显示模式,可以正常显示
    getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);