scene 1
Problem Description
Normally, when EditText
the input box is clicked, the soft keyboard pops up, but the keyboard blocks EditText
the display.
solution
AndroidManifest
In the file, Activity is newly configured android:windowSoftInputMode
, and the setting value is adjustPan
or adjustResize
, as follows:
<activity
android:name="xxx"
android:windowSoftInputMode="adjustPan" />
The difference between adjustPan and adjustResize
adjustPan
When this parameter is configured, the entire interface will move upward and the input box will be displayed, but the layout of the interface will not be changed.adjustResize
Configuring this parameter, the system will recalculate the interface size after removing the soft keyboard, and use less interface area to display content, including the input box.
Scene 2
Problem Description
In hybrid development, when the application loads the web page in non-full-screen modeWebView
and clicks on the input box, the soft keyboard is blocked.
solution
The operation method is the same as above, but only the setting value is supported adjustResize
, and the setting adjustPan
is invalid.
Scene 3
Problem Description
- In hybrid development, the application is in full-screen mode (Application or activity uses Fullscreen theme, immersive status bar,
Immersive Mode
etc.) , WebView loads the web page, clicks on the input box, and the soft keyboard is blocked. android:windowSoftInputMode
Setting the value toadjustPan
oradjustResize
has no effect.- This is a system-level pitfall.
solution
plan 1
Try to avoid using panorama mode when one Activity
contains WebView
controls . (Of course, this method treats the symptoms but not the root cause)
Scenario 2
stackflow
There is a great guy who provided a solution. ( stackflow address )
The specific code is as follows,
import android.app.Activity;
import android.graphics.Rect;
import android.os.Build;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;
/**
* 修复WebView全屏模式下,软键盘遮挡问题
*/
public final class AndroidBug5497Workaround {
private View mChildOfContent;
private int usableHeightPrevious;
private FrameLayout.LayoutParams frameLayoutParams;
private int contentHeight;
private boolean isFirst = true;
private int statusBarHeight;
public static void assistActivity(Activity activity) {
new AndroidBug5497Workaround(activity);
}
private AndroidBug5497Workaround(Activity activity) {
//获取状态栏的高度
int resourceId = activity.getResources().getIdentifier("status_bar_height", "dimen", "android");
statusBarHeight = activity.getResources().getDimensionPixelSize(resourceId);
FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);
mChildOfContent = content.getChildAt(0);
//界面出现变动都会调用这个监听事件
mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
public void onGlobalLayout() {
if (isFirst) {
contentHeight = mChildOfContent.getHeight();//兼容华为等机型
isFirst = false;
}
possiblyResizeChildOfContent();
}
});
frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams();
}
/**
* 重新调整布局的高度
*/
private void possiblyResizeChildOfContent() {
int usableHeightNow = computeUsableHeight();
//当前可见高度和上一次可见高度不一致 布局变动
if (usableHeightNow != usableHeightPrevious) {
int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();
int heightDifference = usableHeightSansKeyboard - usableHeightNow;
if (heightDifference > (usableHeightSansKeyboard / 4)) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
frameLayoutParams.height = usableHeightSansKeyboard - heightDifference + statusBarHeight;
} else {
frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
}
} else {
frameLayoutParams.height = contentHeight;
}
mChildOfContent.requestLayout();
usableHeightPrevious = usableHeightNow;
}
}
/**
* 计算mChildOfContent可见高度
*
* @return
*/
private int computeUsableHeight() {
Rect r = new Rect();
mChildOfContent.getWindowVisibleDisplayFrame(r);
return (r.bottom - r.top);
}
}
- Just add this class to the project and call it in the corresponding method
Activity
.onCreate()
AndroidBug5497Workaround.assistActivity(this);
AndroidBug5497Workaround
Class analysis:
-
By
findViewById(android.R.id.content)
obtaining the root View of the developer-controllable area of the Activity interface. ( In full screen mode, it is the entire screen area; in non-full screen mode, it is the area except the status bar ) -
mChildOfContent = content.getChildAt(0);
, getActivity
the layoutView
( that is, bysetContentView()
settingView
). -
View.getViewTreeObserver()
Get an observer object that specifically monitors changes in the current View tree . -
Since the pop-up of the soft keyboard will cause the global layout (GlobalLayout) of the View tree to change, bind the observer object to monitor the changes in the current View tree
addOnGlobalLayoutListener
. -
Once
addOnGlobalLayoutListener
the monitoring is triggered, the main method is to callpossiblyResizeChildOfContent()
the method and reset the available area after the interface changes. -
possiblyResizeChildOfContent()
In this method,heightDifference > (usableHeightSansKeyboard / 4)
it is judged that only when the height of the interface changes by more than 1/4, the height will be reset to ensure that the pop-up of the soft keyboard is responded to and other interface changes are excluded. -
computeUsableHeight()
It is to calculate the available height for re-adjusting the layout after removing the keyboard.
Summary of problems with soft keyboard blocking interface
Android input box soft keyboard occlusion problem usually has the following three situations:
-
In the interface without WebView:
Configure as requiredandroid:windowSoftInputMode
, asadjustPan
oradjustResize
. -
In the interface with WebView:
non-full-screen mode:
configuredandroid:windowSoftInputMode
asadjustResize
.
Full screen mode:
AAndroidBug5497Workaround
new class is added to the project, which is a perfect solution.