zoukankan      html  css  js  c++  java
  • 记 Android 部分布局忽然无法显示

    总结:这是一个一开始方向错误的问题

    某次,APK在测试手机上正常使用,故换了个荣耀X20的设备,想着兼容性应该没有问题,

    结果,忽然发现A页面,一个底部布局无法显示,其它页面这个布局可以显示(使用的include),

    以为出现了什么奇葩的bug

    查找许久,修改测试调整

    后发现,原来是A页面初始化时,添加了一个隐藏软键盘的代码,如下

    import android.app.Activity;
    import android.content.Context;
    import android.graphics.Rect;
    import android.view.View;
    import android.view.ViewTreeObserver;
    import android.view.inputmethod.InputMethodManager;
    import java.util.LinkedList;
    import java.util.List;
    
    public class SoftKeyboardStateHelper implements ViewTreeObserver.OnGlobalLayoutListener {
    
        public interface SoftKeyboardStateListener {
            void onSoftKeyboardOpened(int keyboardHeightInPx);
            void onSoftKeyboardClosed();
        }
    
        private final List<SoftKeyboardStateListener> listeners = new LinkedList<SoftKeyboardStateListener>();
        private final View activityRootView;
        private int        lastSoftKeyboardHeightInPx;
        private boolean    isSoftKeyboardOpened;
    
        public SoftKeyboardStateHelper(View activityRootView) {
            this(activityRootView, false);
        }
    
        public SoftKeyboardStateHelper(View activityRootView, boolean isSoftKeyboardOpened) {
            this.activityRootView     = activityRootView;
            this.isSoftKeyboardOpened = isSoftKeyboardOpened;
            activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(this);
        }
    
        @Override
        public void onGlobalLayout() {
            final Rect r = new Rect();
            //r will be populated with the coordinates of your view that area still visible.
            activityRootView.getWindowVisibleDisplayFrame(r);
    
            final int heightDiff = activityRootView.getRootView().getHeight() - (r.bottom - r.top);
            if (!isSoftKeyboardOpened && heightDiff > 100) { // if more than 100 pixels, its probably a keyboard...
                isSoftKeyboardOpened = true;
                notifyOnSoftKeyboardOpened(heightDiff);
            } else if (isSoftKeyboardOpened && heightDiff < 100) {
                isSoftKeyboardOpened = false;
                notifyOnSoftKeyboardClosed();
            }
        }
    
        public void setIsSoftKeyboardOpened(boolean isSoftKeyboardOpened) {
            this.isSoftKeyboardOpened = isSoftKeyboardOpened;
        }
    
        public boolean isSoftKeyboardOpened() {
            return isSoftKeyboardOpened;
        }
    
        /**
         * Default value is zero (0)
         * @return last saved keyboard height in px
         */
        public int getLastSoftKeyboardHeightInPx() {
            return lastSoftKeyboardHeightInPx;
        }
    
        public void addSoftKeyboardStateListener(SoftKeyboardStateListener listener) {
            listeners.add(listener);
        }
    
        public void removeSoftKeyboardStateListener(SoftKeyboardStateListener listener) {
            listeners.remove(listener);
        }
    
        private void notifyOnSoftKeyboardOpened(int keyboardHeightInPx) {
            this.lastSoftKeyboardHeightInPx = keyboardHeightInPx;
    
            for (SoftKeyboardStateListener listener : listeners) {
                if (listener != null) {
                    listener.onSoftKeyboardOpened(keyboardHeightInPx);
                }
            }
        }
    
        private void notifyOnSoftKeyboardClosed() {
            for (SoftKeyboardStateListener listener : listeners) {
                if (listener != null) {
                    listener.onSoftKeyboardClosed();
                }
            }
        }
    
        /**
         * 判断软键盘是否弹出
         */
        public static boolean isSHowKeyboard(Context context, View v) {
            InputMethodManager imm = (InputMethodManager) context.getSystemService(context.INPUT_METHOD_SERVICE);
            if (imm.hideSoftInputFromWindow(v.getWindowToken(), 0)) {
                imm.showSoftInput(v, 0);
                return true;
                //软键盘已弹出
            } else {
                return false;
                //软键盘未弹出
            }
        }
    
    }
    View Code
        public static void setBottomBySoftKeyBoard(Activity activity, int root, View bottom) {
            final SoftKeyboardStateHelper softKeyboardStateHelper = new SoftKeyboardStateHelper(activity.findViewById(root));
            softKeyboardStateHelper.addSoftKeyboardStateListener(new SoftKeyboardStateHelper.SoftKeyboardStateListener() {
                @Override
                public void onSoftKeyboardOpened(int keyboardHeightInPx) {
                    bottom.setVisibility(View.GONE);
                }
    
                @Override
                public void onSoftKeyboardClosed() {
                    bottom.setVisibility(View.VISIBLE);
                }
            });
        }
    }
    

    后来发现这种写法,部分版本手机,如果没有开启软键盘的情况下,会将底部布局隐藏  

    后来修改为如下写法,此方法为标准写法,理论上应该兼容大部分手机

    ((InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
    

      

    但是后来,低版本的手机没有什么问题,部分高版本手机,会直接闪退

    再后来,添加了判断,如果有软键盘,再隐藏,

            if (SoftKeyboardStateHelper.isSHowKeyboard(activity, v)) {
                ((InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
            }
    

      

    最后修复了这个奇葩的问题

  • 相关阅读:
    Mybatis总结(mybatis plus待更新)
    maven配置(IDEA)quickstart,IDEA上maven细节配置
    (已解决)C3P0数据库使用配置文件链接,报错:com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector run
    angular--ng-template&ngTemplateOutlet的用法

    Array.from()和Array.of()用法
    Object.create()
    继承
    Object类型
    剩余参数
  • 原文地址:https://www.cnblogs.com/uoky/p/15619058.html
Copyright © 2011-2022 走看看