Summary of Android soft keyboard blocking interface problems

scene 1

Problem Description

Normally, when EditTextthe input box is clicked, the soft keyboard pops up, but the keyboard blocks EditTextthe display.

solution

AndroidManifestIn the file, Activity is newly configured android:windowSoftInputMode, and the setting value is adjustPanor adjustResize, as follows:

<activity
    android:name="xxx"
    android:windowSoftInputMode="adjustPan"  />

The difference between adjustPan and adjustResize

  • adjustPanWhen 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.
  • adjustResizeConfiguring 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 adjustPanis 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 Modeetc.) , WebView loads the web page, clicks on the input box, and the soft keyboard is blocked.
  • android:windowSoftInputModeSetting the value to adjustPanor adjustResizehas no effect.
  • This is a system-level pitfall.

solution

plan 1

Try to avoid using panorama mode when one Activitycontains WebViewcontrols . (Of course, this method treats the symptoms but not the root cause)

Scenario 2

stackflowThere 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);

AndroidBug5497WorkaroundClass analysis:

  1. 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 )

  2. mChildOfContent = content.getChildAt(0); , get Activity the layout View ( that is, by setContentView() settingView ).

  3. View.getViewTreeObserver()Get an observer object that specifically monitors changes in the current View tree .

  4. 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.

  5. Once addOnGlobalLayoutListenerthe monitoring is triggered, the main method is to call possiblyResizeChildOfContent()the method and reset the available area after the interface changes.

  6. 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.

  7. 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 required android:windowSoftInputMode, as adjustPanor adjustResize.

  • In the interface with WebView:
    non-full-screen mode:
    configured android:windowSoftInputModeas adjustResize.
    Full screen mode:
    A AndroidBug5497Workaroundnew class is added to the project, which is a perfect solution.

Reference article

Guess you like

Origin blog.csdn.net/qq_22255311/article/details/129446787