Uni App uses the Android native plug-in pageEditTextVery unfriendly, clickEditTextThe keyboard may cover the plugin page or the keyboard may jump frequently.

Solution:

  • Principle: Get the bottom of the current pagecontentThe height of theactivity.findViewById(android.R.id.content).getChildAt(0), listen to the bottom layercontentAfter the height changes, the layout is updated again
mContentView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    public void onGlobalLayout(a) {// The soft keyboard pops up and the system navigation bar hides and displays
        SetHeight (Integer);}});// Make a shake proof here
private void setHeight(int height) {
    if(mFrameLayoutParams.height ! = height) {// Unnecessary updates are not needed
        mContentView.postDelayed(() -> {
            // Uni has been updated, there is no need to update it again
            // Uni is not updated, it is not updated, so it is delayed to update the layout
            if(mFrameLayoutParams.height ! = height) { mFrameLayoutParams.height = height; mContentView.requestLayout();// Triggers layout updates}},20); }}Copy the code

The detailed code is as follows:

  • inMyPandoraEntryActivityLower delay initialization singleton
SoftKeyboardFixerForFullscreenUtil.assistActivity(this);// It is recommended to delay initialization by 1 second
Copy the code
  • SoftKeyboardFixerForFullscreenUtilThe complete code is as follows
/ * * * to solve the full screen Activity blocked by keyboard input box * from: https://blog.csdn.net/passerby_b/article/details/82686662 * note: * 1. To call assistActivity after setContentView! * 2. If the landscape input method is not full screen, you need to adapt yourself! * 3. No problem is found in the self-test, but the compatibility cannot be 100% guaranteed ~ * 4. 

* update Cooper 2018-9-13 13:27:59 * 1 Solve the problem that the hidden display layout of the virtual navigation bar does not automatically adapt (Samsung Note8 8.0 has no problem in horizontal or vertical screen test, Vivo without virtual button 6.0 has no problem in test) * 2. Solve the problem of mismatch in split screen mode (Samsung Note8 8.0 measured horizontal screen vertical screen is no problem) * 3. Optimize code * < p > * reference: https://blog.csdn.net/smileiam/article/details/69055963 * reference: * reference: https://blog.csdn.net/auccy/article/details/80632429 https://github.com/yy1300326388/AndroidBarUtils/blob/master/app/src/main/java/cn/zsl/androidbarutils/utils/AndroidBarUti AndroidBug5497Workaround is the original version of AndroidBug5497Workaround, but the original version of AndroidBug5497Workaround is not comprehensive enough, especially the problem of virtual navigation. https://www.jianshu.com/p/a95a1b84da11 */

public class SoftKeyboardFixerForFullscreenUtil { public static void assistActivity(Activity activity) { new SoftKeyboardFixerForFullscreenUtil(activity); } private final View mContentView;// We set the contentView private final FrameLayout.LayoutParams mFrameLayoutParams;// We set the layoutParams of the contentView // private boolean isNavigationShowing = false; // This is not used // private boolean isFullscreenMode = false; // This is not used // private int barNavigationHeight = 0; // The height of the virtual navigation bar is useless // private int barNavigationWidth = 0; // Virtual navigation width, no use private int barStatusHeight = 0;// Status bar height private int lastUsableHeight = 0;// Last available height // private int lastUsableWidth = 0; // The last available width private SoftKeyboardFixerForFullscreenUtil(final Activity activity) { //region is used to listen for virtual keys, but the callback is later than the layout callback, so it is not used. I put it here to give you some ideas for the future. // //1. Add visible change events for system components to the DecorView // View decorView = activity.getWindow().getDecorView(); // isNavigationShowing = ((decorView.getSystemUiVisibility() & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0); // isFullscreenMode = ((decorView.getSystemUiVisibility() & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0); / / API 16 above / / decorView. SetOnSystemUiVisibilityChangeListener (new View. OnSystemUiVisibilityChangeListener () {/ / reference: https://blog.csdn.net/auccy/article/details/80632429 // @Override // public void onSystemUiVisibilityChange(int visibility) { // if ((visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0) { // isNavigationShowing = true; // } else { // isNavigationShowing = false; / /} // if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) { // isFullscreenMode = true; // } else { // isFullscreenMode = true; / /} / /} / /}); //endregion //1. Obtain the status bar height and navigation bar height and width. barStatusHeight = getStatusBarHeight(activity); //barNavigationHeight = getNavigationBarHeight(activity); //barNavigationWidth = getNavigationBarWidth(activity); //2. Locate the Activity's outermost layout control, which is actually a DecorView. The control used is FrameLayout final FrameLayout content = activity.findViewById(android.R.id.content); //3. Get the View that setContentView put in mContentView = content.getChildAt(0); //4. Get the View layout parameters we set, mainly adjust the parameters to achieve the soft keyboard pop-up up mFrameLayoutParams = (FrameLayout.LayoutParams) mContentView.getLayoutParams(); //5. Add a listener for layout changes to our View to implement layout actions (this listener can also be triggered by the pop-up collapse of the virtual navigation bar!) mContentView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { public void onGlobalLayout(a) {// The soft keyboard pops up and the system navigation bar hides and displays // int heightRoot = content.getRootView().getHeight(); // Contains the height of the virtual keys (if any) int heightDecor = content.getHeight();// Does not contain the height of the virtual keys, including the height of the status bar // Log.e("SoftKeyboardFi", "heightDecor " + heightDecor); int usableHeight = computeUsableHeight();// We set setContentView to the height of the view if(usableHeight ! = lastUsableHeight) { lastUsableHeight = usableHeight;// Prevent repeated changes int heightDifference = heightDecor - usableHeight; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && activity.isInMultiWindowMode()) {// In split screen mode if (heightDifference > 0) {// Split screen mode, as long as the change of artificial pop-up keyboard, because the split screen may be the Activity at the top of the phone screen, pop-up input method just cover a little ~ if not suitable, you need to adapt yourself! setHeight(heightDecor - heightDifference); // The height of the status bar cannot be added } else { setHeight(FrameLayout.LayoutParams.MATCH_PARENT);// Restore the default height, cannot use the calculated value, because the virtual navigation bar also changes the height when it is displayed or hidden}}else { if (heightDifference > (heightDecor / 4)) {// Height changes over a quarter of decor considered soft keyboard pop-up events, so why not use screen height? At first I thought this would work in split-screen mode, but it didn't work. Log.e("SoftKeyboardFi"."heightDifference > (heightDecor / 4) true"); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { setHeight(heightDecor - heightDifference + barStatusHeight);// Why add status bar height here? } else { setHeight(heightDecor - heightDifference);// Do not add status bar height here? I don't know why. It's the original. Let's leave it at that. Meet again ~ } if (null! = AppFloatView.instance) {if(AppFloatView.get().appFloatIsShow()) { AppFloatView.get().hideFloat(); }}}else { Log.e("SoftKeyboardFi"."heightDifference > (heightDecor / 4) false"); setHeight(FrameLayout.LayoutParams.MATCH_PARENT);// Restore the default height, cannot use the calculated value, because the virtual navigation bar also changes the height when it is displayed or hidden if (null! = AppFloatView.instance) {if(! AppFloatView.get().appFloatIsShow() && ! AppFloatView.IS_HIDE_LAYOUT) { AppFloatView.get().showFloat(); }}}}}}}); }private void setHeight(int height) { if(mFrameLayoutParams.height ! = height) {// Unnecessary updates are not needed mContentView.postDelayed(() -> { // Uni has been updated, there is no need to update it again // Uni is not updated, it is not updated, so it is delayed to update the layout if(mFrameLayoutParams.height ! = height) { mFrameLayoutParams.height = height; mContentView.requestLayout();// Triggers layout updates}},20); }}private int computeUsableHeight(a) { Rect r = new Rect(); mContentView.getWindowVisibleDisplayFrame(r); // In full screen mode, return r.box, which is the height of the status bar return (r.bottom - r.top); } private int computeUsableWidth(a) { Rect r = new Rect(); mContentView.getWindowVisibleDisplayFrame(r); // In full screen mode: return to R.box. R.box is the height of the status bar. // Landscape is the width return (r.right - r.left); } // The following code comes from: https://github.com/yy1300326388/AndroidBarUtils/blob/master/app/src/main/java/cn/zsl/androidbarutils/utils/AndroidBarUti ls.java // Complete code, full screen problem. private static final String STATUS_BAR_HEIGHT_RES_NAME = "status_bar_height"; private static final String NAV_BAR_HEIGHT_RES_NAME = "navigation_bar_height"; private static final String NAV_BAR_WIDTH_RES_NAME = "navigation_bar_width"; /** * Get the status bar height **@param context context * @returnStatus bar height */ private static int getStatusBarHeight(Activity context) { // Get the status bar height return getBarHeight(context, STATUS_BAR_HEIGHT_RES_NAME); } /** * Get the navigation bar height **@param activity activity * @returnNavigation bar height */ private static int getNavigationBarHeight(Activity activity) { if (hasNavBar(activity)) { // Get the navigation height return getBarHeight(activity, NAV_BAR_HEIGHT_RES_NAME); } else { return 0; }}/** * Gets the width of the navigation bar in landscape mode **@param activity activity * @returnWidth of navigation bar */ private static int getNavigationBarWidth(Activity activity) { if (hasNavBar(activity)) { // Get the navigation height return getBarHeight(activity, NAV_BAR_WIDTH_RES_NAME); } else { return 0; }}/** * Get Bar height **@param context context * @paramBarName name *@returnThe Bar height * / private static int getBarHeight(Context context, String barName) { // Get the status bar height int resourceId = context.getResources().getIdentifier(barName, "dimen"."android"); return context.getResources().getDimensionPixelSize(resourceId); } /** * Whether NavigationBar ** is available@paramActivity context *@returnNavigationBar */ is available private static boolean hasNavBar(Activity activity) { WindowManager windowManager = activity.getWindowManager(); Display d = windowManager.getDefaultDisplay(); DisplayMetrics realDisplayMetrics = new DisplayMetrics(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { d.getRealMetrics(realDisplayMetrics); } int realHeight = realDisplayMetrics.heightPixels; int realWidth = realDisplayMetrics.widthPixels; DisplayMetrics displayMetrics = new DisplayMetrics(); d.getMetrics(displayMetrics); int displayHeight = displayMetrics.heightPixels; int displayWidth = displayMetrics.widthPixels; return (realWidth - displayWidth) > 0 || (realHeight - displayHeight) > 0; }}Copy the code

Refer to this article for details: blog.csdn.net/passerby_b/…