Android開發-狀態列著色原理和API版本號碼相容處理

來源:互聯網
上載者:User

標籤:dimen   text   var   系統配置   背景   pretty   views   recycle   orm   

介紹

先上實際,有三個版本號碼請注意區分API版本號碼

API>=20 API=19 API<19

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvQ2FyZDM2MTQwMTM3Ng==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="<19" title="">

以上的效果我們稱之為對狀態列的著色,而非沈浸式狀態列。那是另外的東西。
想要實現以上的效果並不難,閱讀本文瞭解原理後,就會認為想要以上的效果真的非常easy。
本文旨在總結我的理解告訴讀者一步步實現狀態列著色的原理。

原理第一步-設定透明狀態列

對狀態列的控制一切基礎都源於

    static public void setTranslucentWindows(Activity activity) {        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {            //透明狀態列            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);        }    }

請注意該Flag標識的API版本號碼為19,也就是僅僅能在API>=19以上實現透明狀態列,這就是上文用API區分的原因。

註:下面style樣式同上代碼,可是有相容問題。建議直接使用代碼設定
<item name="android:windowTranslucentStatus">true</item>

第二步-padding出預留空間

設定透明狀態列之後,內容會頂到螢幕頂部會和狀態列中的內容重疊。

就須要設定padding出和狀態列相同的高度。防止重疊
有兩種解決方案:

  1. XML中設定:對某個View設定android:fitsSystemWindows="true"(API+14)系統布局時自己主動找到最外層的View設定paddingTop

  2. 代碼控制:確定狀態列高度然後給須要View設定paddingTop的值

在XML中直接設定屬性比較簡單。可是有局限性,僅僅對最外層View有效。假設是Fragment的View視圖中設定fitsSystemWindows然後被加入到螢幕上無效。


代碼控制,可以解決Fragment的問題。可是確定狀態列高度有點麻煩,一般來說狀態列高度都是24dp,保險起見還是須要讀取系統的配置高度,還有設定padding有時也會失效,就須要handler.post(new Runnable())來保證代碼的運行

讀取系統配置的狀態列高度代碼:
    /**     * 19API以上 讀取到狀態列高度才有意義     *     * @param context     * @return     */    static public int getStatusBarHeight(Context context) {        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {            int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");            return resourceId > 0 ? context.getResources().getDimensionPixelSize(resourceId) : 0;        } else {            return 0;        }    }
第三步-著色

這裡先說明前兩步的結果;

  • API<19:不運行
  • API=19:黑灰漸進透明的狀態列
  • API>=20:系統會自己主動產生一個半透明的狀態列

所以就須要我們對第二步中產生的預留空間設定顏色,相同有兩種方法:

  1. 加入View:對整個視圖的父容器FrameLayout(ID=android.R.id.content)加入一個狀態列高度帶有顏色的View。覆蓋到狀態列。
  2. 自己主動渲染:對設定了paddingTop的控制項。設定背景色。當該控制項被padding處理時,顏色也同一時候渲染到了狀態列中。

加入覆蓋狀態列View的代碼:
    /**     * 設定狀態列顏色為App主色     * 配合{@link #setTranslucentWindows(Activity)}方法使用     * 主要方法為加入一個View並設定背景色加入到系統contentView中     *     * @param activity     */    static public void addStatusBarBackground(Activity activity) {        int height;        height = getStatusBarHeight(activity);        if (height <= 0) {            return;        }        FrameLayout layout = (FrameLayout) activity.findViewById(android.R.id.content);        FrameLayout statusLayout = new FrameLayout(activity);        statusLayout.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, height));        TypedValue typedValue = new TypedValue();        TypedArray a = activity.obtainStyledAttributes(typedValue.data, new int[]{R.attr.colorPrimary});        int color = a.getColor(0, 0);        a.recycle();        statusLayout.setBackgroundColor(color);        layout.addView(statusLayout);    }
特殊的API21+
當API21+:可以調用系統API直接對狀態列著色if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.LOLLIPOP){    this.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);    this.getWindow().setStatusBarColor(ContextCompat.getColor(this,R.color.red_normal));}
總結

實現狀態列著色並不複雜,僅僅須要三步。真正使用時事實上就是幾行代碼或者幾個方法調用。可是在實際使用中須要考慮實際需求,相容問題。搭配使用每一步的使用就能實現我們想要的效果。

如上文的實現就是:Activity狀態列透明,導航搜尋欄View背景色透明paddingTop狀態列高度,覆蓋在圖片之上,而圖片沒有不論什麼控制。

Android開發-狀態列著色原理和API版本號碼相容處理

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.