Android实现登录界面键盘不遮挡登录按钮

最近在做安卓开发的时候,出了一个需求要求登录界面输入框当弹出键盘的时候,不能遮挡输入框下面的按钮。研究了两天终于找到了解决方法。

起初以为安卓无法实现这种功能,一般安卓开发需求都是键盘不遮挡输入框。这时我们可以在清单配置文件中通过设置该Activity的WindowSoftInput=adjustPan,此时,当点击输入框,弹出软键盘的时候,界面会自适应屏幕,使软键盘不遮挡按钮。或者用scrollView包裹整个界面的View,这样即使不配置WindowSoftInput=adjustPan也能达到键盘不遮挡输入框的效果,不过此种方法后来发现有一定局限性。就是假如一个页面用dialog展示的话,当页面超出一屏高度的时候,当点击页面下的一个输入框,第一次会正常滚动到键盘之上防止遮挡,但是此时隐藏键盘再次点击该输入框,scrollView不会滚动,形成遮挡,暂时未找到这种情况的解决方案,以后找到方案的话,会和大家分享,也希望看到这篇博客的大牛,有解决方案的话通知一下小弟。

若要实现不遮挡输入框下的按钮,有两种解决方法,一种就是把整个界面布局写在屏幕的上部,当弹出软键盘的时候,由于键盘高度达不到按钮在键盘上的高度,故可以实现,比如qq和微信。

另外一种方法,就是想办法监听软键盘是否弹出和隐藏,然后根据软键盘弹出状态使整个布局向上滚动或向下滚动到原点。由于Android和iOS机制不同,iOS可以监听软键盘的状态,Android却没有提供监听软键盘状态的方法。故先需要设法去获取安卓软键盘的状态。下面就是自定义布局监听布局尺寸是否改变来判断Android是否弹出软键盘。

public class LinearLayoutView extends LinearLayout{
   public static final int KEYBORAD_HIDE = 0;
   public static final int KEYBORAD_SHOW = 1;
   private static final int SOFTKEYPAD_MIN_HEIGHT = 50;
   private Handler uiHandler = new Handler();
   public LinearLayoutView(Context context) {
      super(context);
   }
   public LinearLayoutView(Context context, AttributeSet attrs) {
      super(context, attrs);
   }
   @Override
   public void onSizeChanged(int w,final int h, int oldw,final int oldh) {
      // TODO Auto-generated method stub
      super.onSizeChanged(w, h, oldw, oldh);
      uiHandler.post(new Runnable() {
         @Override
         public void run() {
            if (oldh - h > SOFTKEYPAD_MIN_HEIGHT){
               keyBordStateListener.stateChange(KEYBORAD_SHOW,oldh-h);
            }else {
               if(keyBordStateListener != null){
                  keyBordStateListener.stateChange(KEYBORAD_HIDE,0);}
            }
         }
      });
   }
   private KeyBordStateListener  keyBordStateListener;
   public void setKeyBordStateListener(KeyBordStateListener keyBordStateListener) {
      this.keyBordStateListener = keyBordStateListener;
   }
   public interface KeyBordStateListener{
      public void stateChange(int state,int height);
   }
}
这里我们重写View的 onSizeChanged方法,同时需要在清单配置文件中把WindowSoftInput=adjustResize;这是布局会根据屏幕内部view变化改变布局尺,
SOFTKEYPAD_MIN_HEIGHT这个值是自己默认的高度,软键盘的高度会大于这个值,当oldh-h的值(这个值就是布局尺寸改变的大小,也是软键盘高度的大小)大于
SOFTKEYPAD_MIN_HEIGHT的时候,就说明此时弹出了软键盘,然后通过接口回调把这个值传回到登录界面。

在登录界面实现这个自定义view类里面的接口,获得软键盘的高度,此时判断按钮距离屏幕的高度,然后通过判断按钮高度值和软键盘高度值之差确定按钮是否居于软键盘之下,若居于软键盘之下,则让整个根view向上滚动两值之差和按钮高度的和。此时就可以实现该需求。登录界面实现该接口的代码如下:

public void stateChange(int state, int height) {
      switch (state) {
         case LinearLayoutView.KEYBORAD_HIDE:
            LogUtill.debug("键盘隐藏");
            loginscrollview.scrollTo(0, 0);
            break;
         case LinearLayoutView.KEYBORAD_SHOW:
            mRootview.scrollTo(0, 0);
            loginscrollview.scrollTo(0, 0);
            LogUtill.debug("键盘打开" );
            int[] locations = new int[2];
            submit_btn.getLocationOnScreen(locations);
            int keyheight = height;
            int height2 = DeviceUtil.getDisplayMetricsHeight(LoginActivity.this) - locations[1] - Util.dip2px(LoginActivity.this, 45);
            LogUtill.debug("keyheight====="+keyheight+",height======="+height2);
            if (height2 < keyheight) {
               loginscrollview.scrollTo(0, keyheight-height2);
            }
            break;
      }
   }

 
  

因为adjustResize是要重绘页面计算高度,所以在一些手机上,会有短暂的空白停留,显得不流畅,配置高的手机有些没有这种问题。不能两全其美。


你可能感兴趣的:(安卓系统键盘遮挡)