Android 全面屏下開啟底部虛擬導航按鈕時界面被遮擋的問題

???????目前大家手里握的都是全面屏的手機,而且每家廠商都對全面屏的手機做了手勢的支持 確實是從體驗上得到了很大的提升,再也不是當年16:9的屏 底部再配個三大金剛的導航按鈕 使得有限的可是預覽面積更小了。但是2020年依然會有人不使用全面屏手勢 選擇三大金剛的導航按鈕,這就引出了今天的問題。

癥狀:開啟底部虛擬導航按鈕,進入全屏顯示的頁面,此頁面有輸入框, 這時發(fā)現底部被遮擋的問題

使用全面屏手勢.jpeg
使用導航按鈕.jpeg

看到全屏顯示、界面上還有輸入框,大家肯定會想到鍵盤彈出遮擋的bug,還有這個AndroidBug5497Workaround類(如有沒使用過的小伙伴 代碼貼到下面)

public class AndroidBug5497Workaround {


    // For more information, see https://code.google.com/p/android/issues/detail?id=5497
    // To use this class, simply invoke assistActivity() on an Activity that already has its content view set.

    public static void assistActivity (Activity activity) {
        new AndroidBug5497Workaround(activity);
    }

    private View mChildOfContent;
    private int usableHeightPrevious;
    private FrameLayout.LayoutParams frameLayoutParams;

    private AndroidBug5497Workaround(final Activity activity) {
        FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);
        mChildOfContent = content.getChildAt(0);
        mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            public void onGlobalLayout() {
                possiblyResizeChildOfContent(activity);
            }
        });
        frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams();
    }

    private void possiblyResizeChildOfContent(Activity activity) {
        int usableHeightNow = computeUsableHeight() ;
        if (usableHeightNow != usableHeightPrevious) {

            int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();
            int heightDifference = usableHeightSansKeyboard - usableHeightNow;
            if (heightDifference > (usableHeightSansKeyboard/4)) {
                // keyboard probably just became visible
                frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
            } else {
                // keyboard probably just became hidden
                frameLayoutParams.height = usableHeightSansKeyboard;
            }
            mChildOfContent.requestLayout();
            usableHeightPrevious = usableHeightNow;
        }
    }

    private int computeUsableHeight() {
        Rect r = new Rect();
        mChildOfContent.getWindowVisibleDisplayFrame(r);
        return (r.bottom - r.top);// 全屏模式下: return r.bottom
    }
}

我們今天講的這個問題,其實也是要從這個類來修改


1590656854230.jpg

問題就是我們沒有去掉底部導航按鈕的高度
這個導航欄的高度怎么計算呢?
大部分人會想到拿屏幕的實際高度減去當前可用的高度不就是底部按鈕的高度嗎,我一開始也是這么想的,沒啥大毛病,然后就是一頓擼

/**
     * 獲取屏幕高度
     * @param context
     * @return
     */
    public static int getScreeHeight(Context context) {
        return context.getResources().getDisplayMetrics().heightPixels;
    }

    /**
     * 獲取屏幕寬度
     * @param context
     * @return
     */
    public static int getScreeWidth(Context context) {
        return context.getResources().getDisplayMetrics().widthPixels;
    }

    /**
     * 獲取實際高度
     * @param context
     * @return
     */
    public static int getScreeRealHeight(Context context) {
        Display display = getDisplay(context);
        if (display == null) {
            return 0;
        }
        DisplayMetrics dm = new DisplayMetrics();
        display.getRealMetrics(dm);
        return dm.heightPixels;
    }

    /**
     * 獲取實際寬度
     * @param context
     * @return
     */
    public static int getScreeRealWidth(Context context) {
        Display display = getDisplay(context);
        if (display == null) {
            return 0;
        }
        DisplayMetrics dm = new DisplayMetrics();
        display.getRealMetrics(dm);
        return dm.widthPixels;
    }

    private static Display getDisplay(Context context) {
        WindowManager wm;
        if (context instanceof Activity) {
            Activity activity = (Activity) context;
            wm = activity.getWindowManager();
        } else {
            wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        }
        if (wm != null) {
            return wm.getDefaultDisplay();
        }
        return null;
    }

三星手機測試ok 正想結束戰(zhàn)斗時。拿一加手機一測試 bug又回來了
所以這種方式獲取底部按鈕高度是存在兼容性的
最終給出小伙伴們具有兼容性的底部按鈕高度的獲?。悍謨煞N情況 全面屏和非全面屏的獲取
1. 全面屏下
* 1.1 開啟全面屏開關->返回0
* 1.2 關閉全面屏開關-> 執(zhí)行非全面屏下處理方式

2. 非全面屏下
* 2.1 沒有虛擬鍵->返回0
* 2.1 虛擬鍵隱藏->返回0
* 2.2 虛擬鍵存在且未隱藏-返回虛擬鍵實際高度

public static int getNavigationBarHeightIfRoom(Context context) {
        if(navigationGestureEnabled(context)){
            return 0;
        }
        return getCurrentNavigationBarHeight(((Activity) context));
    }

    /**
     * 全面屏(是否開啟全面屏開關 0 關閉  1 開啟)
     *
     * @param context
     * @return
     */
    public static boolean navigationGestureEnabled(Context context) {
        int val = Settings.Global.getInt(context.getContentResolver(), getDeviceInfo(), 0);
        return val != 0;
    }

    /**
     * 獲取設備信息(目前支持幾大主流的全面屏手機,親測華為、小米、oppo、魅族、vivo都可以)
     *
     * @return
     */
    public static String getDeviceInfo() {
        String brand = Build.BRAND;
        if(TextUtils.isEmpty(brand)) return "navigationbar_is_min";

        if (brand.equalsIgnoreCase("HUAWEI")) {
            return "navigationbar_is_min";
        } else if (brand.equalsIgnoreCase("XIAOMI")) {
            return "force_fsg_nav_bar";
        } else if (brand.equalsIgnoreCase("VIVO")) {
            return "navigation_gesture_on";
        } else if (brand.equalsIgnoreCase("OPPO")) {
            return "navigation_gesture_on";
        } else {
            return "navigationbar_is_min";
        }
    }

    /**
     * 非全面屏下 虛擬鍵實際高度(隱藏后高度為0)
     * @param activity
     * @return
     */
    public static int getCurrentNavigationBarHeight(Activity activity){
        if(isNavigationBarShown(activity)){
            return getNavigationBarHeight(activity);
        } else{
            return 0;
        }
    }

    /**
     * 非全面屏下 虛擬按鍵是否打開
     * @param activity
     * @return
     */
    public static boolean isNavigationBarShown(Activity activity){
        //虛擬鍵的view,為空或者不可見時是隱藏狀態(tài)
        View view  = activity.findViewById(android.R.id.navigationBarBackground);
        if(view == null){
            return false;
        }
        int visible = view.getVisibility();
        if(visible == View.GONE || visible == View.INVISIBLE){
            return false ;
        }else{
            return true;
        }
    }

    /**
     * 非全面屏下 虛擬鍵高度(無論是否隱藏)
     * @param context
     * @return
     */
    public static int getNavigationBarHeight(Context context){
        int result = 0;
        int resourceId = context.getResources().getIdentifier("navigation_bar_height","dimen", "android");
        if (resourceId > 0) {
            result = context.getResources().getDimensionPixelSize(resourceId);
        }
        return result;
    }

到此一連串的問題就解決了?。?!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容