Android mimics QQ login interface to solve soft keyboard occlusion problem

Posted by migmedia on Sat, 18 May 2019 17:50:10 +0200

Original address: https://www.jianshu.com/p/9eb57a8ff5e5


The Android software disk pop-up may obscure some controls on the interface.EditText is generally not blocked when windowSoftInputMode is adjustPan, but if there is a login button below EditText, it may be blocked, but sometimes we want users to click the login button directly after they have finished typing their password, instead of putting the soft keyboard away.This requires adjustResize, a mode that gets the height of the soft keyboard so that we can control the interface precisely.

Before reading this chapter, you should be aware of some of the properties of windowSoftInputMode, especially adjustResize. If you are not familiar with this, it is recommended that you read it first Windows SoftInputMode Analysis of Android Soft Keyboard Look back and forth again.

QQ login interface solves the problem of soft keyboard occlusion very well, of course, the soft keyboard will not block the login button on the large screen mobile phone.Today we will also imitate a QQ login interface, the final effect is as follows:


 



QQ login interface

Listen for soft keyboard pop-up and pick-up events

step1.Specify windowSoftInputMode="adjustResize"

The corresponding Activity setting in AndroidManifest.xml is android:windowSoftInputMode="adjustResize", or it can be set in java code.

step2. Listen for contentView width and height (layout) changes

Get ViewTreeObserver and listen on OnGlobalLayoutListener.Of course, it's best to put these codes in a help class independently.I started with View#addOnLayoutChangeListener, which also listens for soft keyboard popups and retracts, but sometimes there are problems launching a requestLayout() with the onLayoutChange method.

Look at the code to talk:

public class KeyBoardHelper {

    private Activity activity;
    private OnKeyBoardStatusChangeListener onKeyBoardStatusChangeListener;
    private int screenHeight;
    // Blank Height = Screen Height - Height of the visible area of the current Activity
    // Soft keyboard height when blankHeight is not 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);
        }
    }

    public void onCreate() {
        View content = activity.findViewById(android.R.id.content);
        // content.addOnLayoutChangeListener(listener); this method can sometimes cause problems
        content.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayoutListener);
    }

    public void onDestory() {
        View content = activity.findViewById(android.R.id.content);
        content.getViewTreeObserver().removeOnGlobalLayoutListener(onGlobalLayoutListener);
    }

    private OnGlobalLayoutListener onGlobalLayoutListener = new OnGlobalLayoutListener() {

        @Override
        public void onGlobalLayout() {
            Rect rect = new Rect();
            activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
            int newBlankheight = screenHeight - rect.bottom;
            if (newBlankheight != blankHeight) {
                if (newBlankheight > blankHeight) {
                    // keyboard pop
                    if (onKeyBoardStatusChangeListener != null) {
                        onKeyBoardStatusChangeListener.OnKeyBoardPop(newBlankheight);
                    }
                } else { // newBlankheight < blankHeight
                    // keyboard close
                    if (onKeyBoardStatusChangeListener != null) {
                        onKeyBoardStatusChangeListener.OnKeyBoardClose(blankHeight);
                    }
                }
            }
            blankHeight = newBlankheight;
        }
    };

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

    public interface OnKeyBoardStatusChangeListener {

        void OnKeyBoardPop(int keyBoardheight);

        void OnKeyBoardClose(int oldKeyBoardheight);
    }
}

Implement QQ login interface

With this KeyBoardHelper, it is easy to achieve the same effect as the QQ login interface.We don't even need any custom controls.The idea is to move the layout above the login button up when the soft keyboard pops up, just set a negative topMargin for it.

As shown in the diagram:



Diagram of QQ login interface

The MainActivity code is as follows:

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.MarginLayoutParams;

import com.example.qq.support.KeyBoardHelper;
import com.example.qq.support.KeyBoardHelper.OnKeyBoardStatusChangeListener;

public class MainActivity extends Activity {

    private int bottomHeight;
    private KeyBoardHelper boardHelper;
    private View layoutBottom;
    private View layoutContent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_qq_login);

        layoutContent = findViewById(R.id.layout_content);
        layoutBottom = findViewById(R.id.layout_bottom);
        boardHelper = new KeyBoardHelper(this);
        boardHelper.onCreate();
        boardHelper.setOnKeyBoardStatusChangeListener(onKeyBoardStatusChangeListener);
        layoutBottom.post(new Runnable() {
            @Override
            public void run() {
                bottomHeight = layoutBottom.getHeight();
            }
        });
    }

    private OnKeyBoardStatusChangeListener onKeyBoardStatusChangeListener = new OnKeyBoardStatusChangeListener() {

        @Override
        public void OnKeyBoardPop(int keyBoardheight) {

            final int height = keyBoardheight;
            if (bottomHeight > height) {
                layoutBottom.setVisibility(View.GONE);
            } else {
                int offset = bottomHeight - height;
                final ViewGroup.MarginLayoutParams lp = (MarginLayoutParams) layoutContent
                        .getLayoutParams();
                lp.topMargin = offset;
                layoutContent.setLayoutParams(lp);
            }

        }

        @Override
        public void OnKeyBoardClose(int oldKeyBoardheight) {
            if (View.VISIBLE != layoutBottom.getVisibility()) {
                layoutBottom.setVisibility(View.VISIBLE);
            }
            final ViewGroup.MarginLayoutParams lp = (MarginLayoutParams) layoutContent
                    .getLayoutParams();
            if (lp.topMargin != 0) {
                lp.topMargin = 0;
                layoutContent.setLayoutParams(lp);
            }

        }
    };

    @Override
    protected void onDestroy() {
        super.onDestroy();
        boardHelper.onDestory();
    }
}

Layout file: activity_qq_login.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/layout_root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <LinearLayout
        android:id="@+id/layout_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >

        <ImageView
            android:id="@+id/imageView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="68dp"
            android:focusable="true"
            android:scaleType="centerInside"
            android:src="@drawable/qq_ava"
            android:visibility="visible" />

        <LinearLayout
            android:id="@+id/layout_ed"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="18dp"
            android:background="#ffffff"
            android:divider="@drawable/divider"
            android:focusable="true"
            android:focusableInTouchMode="true"
            android:orientation="vertical"
            android:showDividers="middle" >

            <EditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@null"
                android:hint="QQ Number/Cell-phone number/mailbox"
                android:padding="10dp"
                android:textColor="#000000"
                android:textColorHint="#d2d2d2"
                android:textCursorDrawable="@null" />

            <EditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@null"
                android:hint="Password"
                android:padding="10dp"
                android:textColor="#000000"
                android:textColorHint="#d2d2d2"
                android:textCursorDrawable="@null" />
        </LinearLayout>

        <Button
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="14dp"
            android:layout_marginRight="14dp"
            android:layout_marginTop="14dp"
            android:background="@drawable/btn_login"
            android:text="Land"
            android:textSize="17sp" />

        <RelativeLayout
            android:id="@+id/layout_bottom"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent" >

            <TextView
                android:id="@+id/tv_cannot_login"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentBottom="true"
                android:layout_margin="14dp"
                android:text="Can't log on?"
                android:textColor="@color/action_bar_bg"
                android:textSize="14sp" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentBottom="true"
                android:layout_alignParentRight="true"
                android:layout_margin="14dp"
                android:text="new user"
                android:textColor="@color/action_bar_bg"
                android:textSize="14sp" />
        </RelativeLayout>
    </LinearLayout>

    <include
        android:id="@+id/appbar"
        android:layout_width="fill_parent"
        android:layout_height="50dp"
        layout="@layout/appbar" />

</RelativeLayout>

Click me to download the source code


Topics: Android xml Windows Mobile