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:

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:

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>