Android登录软键盘适配

登录是每一个APP必备的功能,我观察了很多的APP,发现登录的账号密码编辑时,对软键盘弹起后的处理并不是很好,在弹起软键盘时,登录按钮会被遮住了,需要手动将软键盘收回,才可以点击登录按钮,这无疑使用户多操作了一步。

下面我随便找了几个没对软键盘弹起后做处理的APP。

  

其实这个问题,可以用一个ScrollView来解决,包裹住需要往上移动的部分布局,在弹起软键盘的时候,将ScrollView滚动到对应编辑框所属的ViewGroup上即可,代码我已经写好了,其实就几行关键代码,直接上代码。

package com.ysbing.loginscrollview;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.EditText;
import android.widget.ScrollView;

/**
 * 对编辑框做软键盘弹起适配
 */
public class LoginScrollView extends ScrollView {

    private int mDefaultBottom = -1;
    private View mChangeView;

    public LoginScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
        post(new Runnable() {
            @Override
            public void run() {
                addListener(LoginScrollView.this, 0);
            }
        });
    }

    private void addListener(ViewGroup viewGroup, int layer) {
        int childCount = viewGroup.getChildCount();
        for (int i = 0; i < childCount; i++) {
            View view = viewGroup.getChildAt(i);
            if (view instanceof EditText) {
                View childParent = view;
                for (int j = 2; j < layer; j++) {
                    childParent = (View) childParent.getParent();
                }
                final View finalChildParent = childParent;
                view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                    @Override
                    public void onGlobalLayout() {
                        mChangeView = finalChildParent;
                        scrollTo(0, finalChildParent.getTop());
                    }
                });
            } else if (view instanceof ViewGroup) {
                addListener((ViewGroup) view, layer + 1);
            }
        }
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        if (b >= mDefaultBottom) {
            mDefaultBottom = b;
        } else {
            if (mChangeView != null) {
                smoothScrollTo(0, mChangeView.getTop());
            }
        }
    }
}复制代码

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.ysbing.loginscrollview.LoginScrollView
        android:id="@+id/loginScrollView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:scrollbars="none"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <android.support.constraint.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginEnd="22dp"
            android:layout_marginStart="22dp"
            android:paddingBottom="4dp"
            android:paddingTop="100dp">

            <TextView
                android:id="@+id/login_textview"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="26dp"
                android:text="手机密码登录"
                android:textSize="18sp"
                android:textStyle="bold"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

            <TextView
                android:id="@+id/login_textview2"
                android:layout_width="wrap_content"
                android:layout_height="60dp"
                android:layout_marginTop="28dp"
                android:gravity="center"
                android:text="+86"
                android:textColor="#d8d8d8"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/login_textview" />

            <View
                android:id="@+id/login_view"
                android:layout_width="0.5dp"
                android:layout_height="20dp"
                android:layout_marginLeft="25dp"
                android:layout_marginStart="25dp"
                app:layout_constraintBottom_toBottomOf="@+id/login_textview2"
                app:layout_constraintStart_toEndOf="@+id/login_textview2"
                app:layout_constraintTop_toTopOf="@+id/login_textview2" />

            <EditText
                android:id="@+id/login_et_account"
                android:layout_width="0dp"
                android:layout_height="0dp"
                android:ems="10"
                android:hint="请输入有效手机号"
                android:inputType="phone"
                android:maxLength="11"
                android:paddingLeft="20dp"
                android:paddingStart="20dp"
                app:layout_constraintBottom_toBottomOf="@+id/login_textview2"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintStart_toEndOf="@+id/login_view"
                app:layout_constraintTop_toTopOf="@+id/login_textview2" />

            <View
                android:id="@+id/login_view2"
                android:layout_width="0dp"
                android:layout_height="0.5dp"
                android:background="#e5e5e5"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/login_textview2" />

            <EditText
                android:id="@+id/login_et_pwd"
                android:layout_width="0dp"
                android:layout_height="60dp"
                android:ems="10"
                android:hint="请输入8-16位长度密码"
                android:inputType="textPassword"
                android:maxLength="16"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/login_view2" />

            <View
                android:id="@+id/login_view3"
                android:layout_width="0dp"
                android:layout_height="0.5dp"
                android:background="#e5e5e5"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/login_et_pwd" />

            <Button
                android:id="@+id/login_btn_ok"
                android:layout_width="0dp"
                android:layout_height="45dp"
                android:layout_marginTop="42dp"
                android:text="登录"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/login_view3" />

        </android.support.constraint.ConstraintLayout>
    </com.ysbing.loginscrollview.LoginScrollView>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="22dp"
        android:layout_marginStart="22dp"
        android:text="忘记密码"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/loginScrollView" />
</android.support.constraint.ConstraintLayout>复制代码

上面的代码复制就可以使用,我就不放到Github上了,下面解释下代码。

看代码中的addListener方法,这个是最核心的部分,看参数,传入了两个参数,第一个参数ViewGroup是用来遍历,第二个参数layer是表示遍及进入了第几层。

在遍历ViewGroup的子View,寻找出ViewGroup中所有的EditText,找到后给EditText加上监听,用于软键盘弹起时滚动ScrollView,这里还有一个需要注意的地方,需要将ScrollView滚动到哪个位置才合适呢?layer在这里起作用了,用来寻找出该EditText所属的ViewGroup,然后将ScrollView滚动到该ViewGroup的顶部,就大功告成了。

XML布局代码就不解释了,还有一个需要注意的是,需要在manifest文件将该Activity添加android:windowSoftInputMode="adjustResize|stateHidden"

windowSoftInputMode在这里也不想多说,另行查资料去。

有兴趣的同学,复制上面的代码运用到项目里吧,最后看看成果。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值