Android 登录页 软键盘不遮盖登录按钮;

小小草图不成敬意;

GIF图是效果,我确保忘记密码按钮也显示出来;

默认情况下,软键盘弹出来时会把登录按钮遮盖住,用户需要点击登录按钮时需要先隐藏软键盘;

使用android:windowSoftInputMode="adjustPan"也只是不让软键盘遮盖输入框,

需要把登录的按钮不被软键盘遮盖,只需要平移登录的Layout就行了;

在软键盘打开时把布局向上移,软键盘关闭时复位;位移的高度就是草图 Y2 - Y1;

可以仅移动登录Layout的布局,也可以移动最外层的rootView布局;

1、计算出登录Layout距离屏幕底部的高度:

 layoutLogin.post(new Runnable() {
          @Override
          public void run() {
              //不可以直接获取控件位置,放在这个里面获取;
              int[] viewLocation = new int[2];
              layoutLogin.getLocationOnScreen(viewLocation); //获取该控价在屏幕中的位置(左上角的点)
//              loginViewtoBottom = UiUtils.getScreenHeight(mContext) - layoutLogin.getBottom(); //getBottom是该控件最底部距离父控件顶部的距离
              loginViewtoBottom = UiUtils.getScreenHeight(mContext) - viewLocation[1] - layoutLogin.getHeight(); //屏幕高度-控件距离顶部高度-控件高度
          }
      });

2、计算出软键盘的高度、以及软键盘打开和关闭的监听:

 下面这个时软键盘监听的工具类:

public class KeyBoardHelper {
    private Activity activity;
    private OnKeyBoardStatusChangeListener onKeyBoardStatusChangeListener;
    private int screenHeight;
    // 空白高度 = 屏幕高度 - 当前 Activity 的可见区域的高度
    // 当 blankHeight 不为 0 即为软键盘高度。
    private int blankHeight = 0;

    public KeyBoardHelper(Activity activity) {
        this.activity = activity;
        screenHeight = activity.getResources().getDisplayMetrics().heightPixels;
        activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
        if (activity.getRequestedOrientation() != ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
            activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        }
        View content = activity.findViewById(android.R.id.content);
        content.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayoutListener);
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
    public void onDestory() {
        View content = activity.findViewById(android.R.id.content);
        content.getViewTreeObserver().removeOnGlobalLayoutListener(onGlobalLayoutListener);
    }

    private ViewTreeObserver.OnGlobalLayoutListener onGlobalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {

        @Override
        public void onGlobalLayout() {
            Rect rect = new Rect();
            activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
            int newBlankheight = screenHeight - rect.bottom;

            if (newBlankheight != blankHeight) {
                if(newBlankheight==0){
                    // keyboard close
                    if (onKeyBoardStatusChangeListener != null) {
//                        onKeyBoardStatusChangeListener.OnKeyBoardClose(newBlankheight);
                        onKeyBoardStatusChangeListener.OnKeyBoardClose(blankHeight);
                    }
                }else{
                    // keyboard pop
                    if (onKeyBoardStatusChangeListener != null) {
                        onKeyBoardStatusChangeListener.OnKeyBoardPop(newBlankheight);
                    }
                }
            }
            blankHeight = newBlankheight;
        }
    };

    public void setOnKeyBoardStatusChangeListener(
            OnKeyBoardStatusChangeListener onKeyBoardStatusChangeListener) {
        this.onKeyBoardStatusChangeListener = onKeyBoardStatusChangeListener;
    }

    public interface OnKeyBoardStatusChangeListener {

        void OnKeyBoardPop(int keyBoardheight);

        void OnKeyBoardClose(int oldKeyBoardheight);
    }
}

3、在Activity中监听软键盘的打开关闭、登录Layout做平移动画;

  软键盘的高度 - 登录Layout距离屏幕底部高度 = 动画位移距离;

KeyBoardHelper keyBoardHelper = new KeyBoardHelper(this);
        keyBoardHelper.setOnKeyBoardStatusChangeListener(new KeyBoardHelper.OnKeyBoardStatusChangeListener() {
            @Override
            public void OnKeyBoardPop(int keyBoardheight) {
                L.i(keyBoardheight + "--open");
//                rootView.scrollTo(0, keyBoardheight - loginViewtoBottom);
                if (animatorUp == null) { //如果每次弹出的键盘高度不一致,就不要这个判断,每次都新创建动画(密码键盘可能和普通键盘高度不一致)
                    int translationY = keyBoardheight - loginViewtoBottom;
                    animatorUp = ObjectAnimator.ofFloat(layoutLogin, "translationY", 0, -translationY);
                    animatorUp.setDuration(360);
                    animatorUp.setInterpolator(new AccelerateDecelerateInterpolator());
                }
                animatorUp.start();

            }

            @Override
            public void OnKeyBoardClose(int oldKeyBoardheight) {
                L.i(oldKeyBoardheight + "--close");
//                rootView.scrollTo(0, 0);
                if (animatorDown == null) {//如果每次弹出的键盘高度不一致,就不要这个判断,每次都新创建动画(密码键盘可能和普通键盘高度不一致)
                    int translationY = oldKeyBoardheight - loginViewtoBottom;
                    animatorDown = ObjectAnimator.ofFloat(layoutLogin,"translationY",-translationY, 0);
                    animatorDown.setDuration(360);
                    animatorDown.setInterpolator(new AccelerateDecelerateInterpolator());
                }
                animatorDown.start();
            }
        });

好了大功告成!!!

 

下面时全部代码,有兴趣的可以看看:

布局文件:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/rootView"
    tools:context=".activity.login.LoginActivity">
    <androidx.appcompat.widget.AppCompatImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
         android:src="@mipmap/login_bg"
        android:scaleType="centerCrop"
        />

    <include layout="@layout/layout_bar" />
    <LinearLayout
        android:id="@+id/layoutLogin"
        android:orientation="vertical"
        android:paddingTop="120dp"
        android:layout_marginRight="@dimen/distance"
        android:layout_marginLeft="@dimen/distance"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <RelativeLayout
            android:layout_marginLeft="22dp"
            android:layout_marginRight="22dp"
            android:layout_width="match_parent"
            android:layout_height="51dp">
            <View
                android:layout_width="match_parent"
                android:background="@color/line"
                android:layout_alignParentBottom="true"
                android:layout_height="1dp"/>
            <androidx.appcompat.widget.AppCompatEditText
                android:id="@+id/etPhone"
                android:layout_width="wrap_content"
                android:minWidth="100dp"
                android:layout_centerInParent="true"
                android:textSize="16dp"
                android:hint="请输入手机号码"
                android:background="@null"
                android:inputType="number"
                android:textColor="@color/main_white"
                android:textColorHint="@color/adadaa"
                android:layout_height="match_parent" />
        </RelativeLayout>
        <RelativeLayout
            android:layout_marginLeft="22dp"
            android:layout_marginRight="22dp"
            android:layout_width="match_parent"
            android:layout_height="51dp">
            <View
                android:layout_width="match_parent"
                android:background="@color/line"
                android:layout_alignParentBottom="true"
                android:layout_height="1dp"/>
            <androidx.appcompat.widget.AppCompatEditText
                android:id="@+id/etPwd"
                android:layout_width="wrap_content"
                android:minWidth="100dp"
                android:layout_centerInParent="true"
                android:textSize="16dp"
                android:hint="请输入登录密码"
                android:password="true"
                android:inputType="textPassword"
                android:background="@null"
                android:textColor="@color/main_white"
                android:textColorHint="@color/adadaa"
                android:layout_height="match_parent" />
        </RelativeLayout>

            <androidx.appcompat.widget.AppCompatTextView
                android:layout_marginRight="44dp"
                android:layout_marginLeft="44dp"
                android:layout_marginTop="20dp"
                android:layout_width="match_parent"
                android:layout_height="44dp"
                android:text="登录"
                android:foreground="?android:attr/selectableItemBackground"
                android:gravity="center"
                android:layout_gravity="center"
                android:textSize="15dp"
                android:textColor="#292929"
                android:background="@drawable/btn_golden_radius"
                />

        <androidx.appcompat.widget.AppCompatTextView
            android:layout_marginRight="44dp"
            android:layout_marginLeft="44dp"
            android:layout_marginTop="20dp"
            android:layout_width="match_parent"
            android:layout_height="44dp"
            android:text="注册"
            android:gravity="center"
            android:layout_gravity="center"
            android:textSize="15dp"
            android:textColor="#292929"
            android:foreground="?android:attr/selectableItemBackground"
            android:background="@drawable/btn_golden_radius"
            />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="忘记密码"
            android:padding="20dp"
            android:layout_gravity="center_horizontal"
            android:textColor="#ffffffff"
            android:gravity="center"
            android:textSize="14dp"
            android:foreground="?android:attr/selectableItemBackground"

            />
    </LinearLayout>

</RelativeLayout>

Activity中的initList函数:

  private int loginViewtoBottom;
    private ObjectAnimator animatorUp,animatorDown;
    @Override
    protected void initList() {
      layoutLogin.post(new Runnable() {
          @Override
          public void run() {
              //不可以直接获取控件位置,放在这个里面获取;
              int[] viewLocation = new int[2];
              layoutLogin.getLocationOnScreen(viewLocation); //获取该控价在屏幕中的位置(左上角的点)
//              loginViewtoBottom = UiUtils.getScreenHeight(mContext) - layoutLogin.getBottom(); //getBottom是该控件最底部距离父控件顶部的距离
              loginViewtoBottom = UiUtils.getScreenHeight(mContext) - viewLocation[1] - layoutLogin.getHeight(); //屏幕高度-控件距离顶部高度-控件高度
          }
      });

        KeyBoardHelper keyBoardHelper = new KeyBoardHelper(this);
        keyBoardHelper.setOnKeyBoardStatusChangeListener(new KeyBoardHelper.OnKeyBoardStatusChangeListener() {
            @Override
            public void OnKeyBoardPop(int keyBoardheight) {
                L.i(keyBoardheight + "--open");
//                rootView.scrollTo(0, keyBoardheight - loginViewtoBottom);
                if (animatorUp == null) { //如果每次弹出的键盘高度不一致,就不要这个判断,每次都新创建动画(密码键盘可能和普通键盘高度不一致)
                    int translationY = keyBoardheight - loginViewtoBottom;
                    animatorUp = ObjectAnimator.ofFloat(layoutLogin, "translationY", 0, -translationY);
                    animatorUp.setDuration(360);
                    animatorUp.setInterpolator(new AccelerateDecelerateInterpolator());
                }
                animatorUp.start();

            }

            @Override
            public void OnKeyBoardClose(int oldKeyBoardheight) {
                L.i(oldKeyBoardheight + "--close");
//                rootView.scrollTo(0, 0);
                if (animatorDown == null) {//如果每次弹出的键盘高度不一致,就不要这个判断,每次都新创建动画(密码键盘可能和普通键盘高度不一致)
                    int translationY = oldKeyBoardheight - loginViewtoBottom;
                    animatorDown = ObjectAnimator.ofFloat(layoutLogin,"translationY",-translationY, 0);
                    animatorDown.setDuration(360);
                    animatorDown.setInterpolator(new AccelerateDecelerateInterpolator());
                }
                animatorDown.start();
            }
        });

    }

涉及到的一些工具类(获取屏幕高度)可以自己实现;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值