狀態(tài)欄著色原理和API版本兼容處理

轉(zhuǎn)載自http://blog.csdn.net/card361401376/article/details/61420830

介紹

先上實際效果圖,有三個版本請注意區(qū)分API版本

API>=20 API=19 API<19
API20
API19
<19

以上的效果我們稱之為對狀態(tài)欄的著色,而非沉浸式狀態(tài)欄阶淘,那是另外的東西沪么。 想要實現(xiàn)以上的效果并不難茉继,閱讀本文了解原理后寄狼,就會覺得想要以上的效果真的很簡單。 本文旨在總結(jié)我的理解告訴讀者一步步實現(xiàn)狀態(tài)欄著色的原理喻圃。

原理

第一步-設(shè)置透明狀態(tài)欄

對狀態(tài)欄的控制一切基礎(chǔ)都源于

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

請注意該Flag標識的API版本為19,也就是只能在API>=19以上實現(xiàn)透明狀態(tài)欄粪滤,這就是上文效果圖用API區(qū)分的原因斧拍。

注:以下style樣式同上代碼,但是有兼容問題杖小,建議直接使用代碼設(shè)置
<item name="Android:windowTranslucentStatus">true</item>

第二步-padding出預留空間

設(shè)置透明狀態(tài)欄之后饮焦,內(nèi)容會頂?shù)狡聊豁敳繒蜖顟B(tài)欄中的內(nèi)容重疊。
就需要設(shè)置padding出和狀態(tài)欄相同的高度窍侧,防止重疊 有兩種解決方法:

  1. XML中設(shè)置:對某個View設(shè)置android:fitsSystemWindows="true"(API+14)系統(tǒng)布局時自動找到最外層的View設(shè)置paddingTop
  2. 代碼控制:確定狀態(tài)欄高度然后給需要View設(shè)置paddingTop的值

在XML中直接設(shè)置屬性比較簡單县踢,但是有局限性,只對最外層View有效伟件,如果是Fragment的View視圖中設(shè)置fitsSystemWindows然后被添加到屏幕上無效硼啤。 代碼控制,能夠解決Fragment的問題斧账,但是確定狀態(tài)欄高度有點麻煩谴返,一般來說狀態(tài)欄高度都是24dp煞肾,保險起見還是需要讀取系統(tǒng)的配置高度,還有設(shè)置padding有時也會失效嗓袱,就需要handler.post(new Runnable())來保證代碼的執(zhí)行

讀取系統(tǒng)配置的狀態(tài)欄高度代碼:

/** 
* 19API以上 讀取到狀態(tài)欄高度才有意義 
* 
* @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; 
    } 
}

第三步-著色

這里先說明前兩步的結(jié)果;

  • API<19:不執(zhí)行
  • API=19:黑灰漸進透明的狀態(tài)欄
  • API>=20:系統(tǒng)會自動生成一個半透明的狀態(tài)欄

所以就需要我們對第二步中產(chǎn)生的預留空間設(shè)置顏色籍救,同樣有兩種方法:

  1. 添加View:對整個視圖的父容器FrameLayout(ID=android.R.id.content)添加一個狀態(tài)欄高度帶有顏色的View,覆蓋到狀態(tài)欄渠抹。
  2. 自動渲染:對設(shè)置了paddingTop的控件蝙昙,設(shè)置背景色,當該控件被padding處理時梧却,顏色也同時渲染到了狀態(tài)欄中奇颠。

添加覆蓋狀態(tài)欄View的代碼:

/** 
* 設(shè)置狀態(tài)欄顏色為App主色 
* 配合{@link #setTranslucentWindows(Activity)}方法使用 
* 主要方法為添加一個View并設(shè)置背景色添加到系統(tǒng)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+:能夠調(diào)用系統(tǒng)API直接對狀態(tài)欄著色

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));
}

總結(jié)

實現(xiàn)狀態(tài)欄著色并不復雜,只需要三步放航,真正使用時其實就是幾行代碼或者幾個方法調(diào)用烈拒。但是在實際使用中需要考慮實際需求,兼容問題广鳍。搭配使用每一步的使用就能實現(xiàn)我們想要的效果荆几。

如上文的效果圖實現(xiàn)就是:
Activity狀態(tài)欄透明,導航搜索欄View背景色透明paddingTop狀態(tài)欄高度赊时,覆蓋在圖片之上伴郁,而圖片沒有任何控制。

備注:我自己在開發(fā)中也遇到了設(shè)置透明狀態(tài)欄引起的其他問題蛋叼,項目設(shè)置了透明狀態(tài)欄焊傅,導致了網(wǎng)頁中鍵盤彈起遮住輸入框,不能自動頂起狈涮,最后采用的解決方案是先判斷鍵盤高度是否高于輸入框的高度狐胎,如果高于就手動將View高度重新設(shè)置;如果有類似的問題歌馍,可以和我交流

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末握巢,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子松却,更是在濱河造成了極大的恐慌暴浦,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件晓锻,死亡現(xiàn)場離奇詭異歌焦,居然都是意外死亡,警方通過查閱死者的電腦和手機砚哆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進店門独撇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事纷铣÷咽罚” “怎么了?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵搜立,是天一觀的道長以躯。 經(jīng)常有香客問我,道長啄踊,這世上最難降的妖魔是什么忧设? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮社痛,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘命雀。我一直安慰自己蒜哀,他們只是感情好,可當我...
    茶點故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布吏砂。 她就那樣靜靜地躺著撵儿,像睡著了一般。 火紅的嫁衣襯著肌膚如雪狐血。 梳的紋絲不亂的頭發(fā)上淀歇,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天,我揣著相機與錄音匈织,去河邊找鬼浪默。 笑死,一個胖子當著我的面吹牛缀匕,可吹牛的內(nèi)容都是我干的纳决。 我是一名探鬼主播,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼乡小,長吁一口氣:“原來是場噩夢啊……” “哼阔加!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起满钟,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤胜榔,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后湃番,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體夭织,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年吠撮,在試婚紗的時候發(fā)現(xiàn)自己被綠了摔癣。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,561評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖择浊,靈堂內(nèi)的尸體忽然破棺而出戴卜,到底是詐尸還是另有隱情,我是刑警寧澤琢岩,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布投剥,位于F島的核電站,受9級特大地震影響担孔,放射性物質(zhì)發(fā)生泄漏江锨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一糕篇、第九天 我趴在偏房一處隱蔽的房頂上張望啄育。 院中可真熱鬧,春花似錦拌消、人聲如沸挑豌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽氓英。三九已至,卻和暖如春鹦筹,著一層夾襖步出監(jiān)牢的瞬間铝阐,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工铐拐, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留徘键,地道東北人。 一個月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓遍蟋,卻偏偏與公主長得像啊鸭,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子匿值,可洞房花燭夜當晚...
    茶點故事閱讀 45,573評論 2 359

推薦閱讀更多精彩內(nèi)容