談談設置狀態欄透明的過程中遇到的問題

        最近的項目中有用到設置狀態欄透明,也就是做沉浸式狀態欄,但是在實現的過程中也遇到了一些問題,所以在這裏做個總結,同時尋求更好的解決方案。網上設置沉浸式狀態欄的方式有好幾種,以下是我採用的方法:

@TargetApi(19)
    public void transparencyBar(Activity activity) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Window window = activity.getWindow();
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
                    | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
            window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.setStatusBarColor(Color.TRANSPARENT);
            window.setNavigationBarColor(Color.TRANSPARENT);
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            ViewGroup decorView = (ViewGroup)activity.getWindow().getDecorView();
            decorView.removeViewAt(decorView.getChildCount() - 1);
            ViewGroup rootView = (ViewGroup)((ViewGroup)activity.findViewById(android.R.id.content)).getChildAt(0);
            rootView.setFitsSystemWindows(false);
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            rootView.requestLayout();
        }
        AndroidBug5497Workaround.assistActivity(this);
    }

        同時要在佈局文件裏設置根佈局android:fitsSystemWindows="false"。這種方式適合商城類詳情頁面,上面是圖片,整個是一個scrollview。

        第一個問題就是如果佈局下方有edittext的話,當其獲得焦點的時候,佈局不會自動調整,有時會出現小鍵盤擋住edittext,用戶體驗不好。所以在上一段代碼的最後引入了AndroidBug5497Workaround這個類。關於這個類的源碼可查看:AndroidBug5497Workaround。引入後即可自動調整佈局。注意:最後一句代碼需與沉浸式狀態欄一起設置,不可單獨設置,否則自動調整的高度會有問題。

        第二個問題是有的手機(例如華爲)底部會有虛擬按鍵,上述的代碼會使虛擬按鍵變成透明,並會擋住下面的佈局。這個時候可以將window.setNavigationBarColor(Color.TRANSPARENT);這句代碼註釋掉,虛擬按鍵就不會變色了。關於虛擬按鍵擋住佈局以及小鍵盤彈出時不調整佈局其實都是因爲android:fitsSystemWindows="false"引起的,但是改爲true呢又會使頂部狀態欄變回去。對於虛擬按鍵的問題,我選擇了判斷當前頁面是否有虛擬按鍵,如果有點話就給被擋住的佈局設置一個底部的padding,高度爲虛擬按鍵的高度,沒有虛擬按鍵的話就不處理。以下爲我採用的判斷是否有虛擬按鍵的代碼:

/**
     * 判斷底部navigator是否已經顯示
     * @param windowManager 當前activity的windowManager(getWindowManager)
     * @return 是否有虛擬按鍵
     */
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
    public boolean hasSoftKeys(WindowManager windowManager){
        Display d = windowManager.getDefaultDisplay();

        DisplayMetrics realDisplayMetrics = new DisplayMetrics();
        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;
        bottomHeight = realHeight - displayHeight;

        return (realWidth - displayWidth) > 0 || (realHeight - displayHeight) > 0;
    }

        其中bottomHeight就是虛擬按鍵的高度,可以存成常量並設置padding。這樣設置之後就可以適配有虛擬按鍵的機型了。對於這些問題可能有更好的解決方案,我的方案也是從網上獲取,希望能夠幫到掉到坑裏的同學。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章