編輯:關於Android編程
最近項目上有需求 ,要求狀態欄透明化 。還有需求是拖動狀態欄標題一下的內容,標題欄的顏色要變化 。這裡所謂的既是狀態欄著色,也是我們經常聽到的沉浸式狀態欄,關於沉浸式的稱呼網上也有很多吐槽的,這裡就不做過多討論了,以下我們統稱狀態欄著色,這樣我覺得更加容易理解。
從Android4.4開始,才可以實現狀態欄著色,並且從5.0開始系統更加完善了這一功能,可直接在主題中設置getWindow().setStatusBarColor(color)來實現,但畢竟4.4+的機器還有很大的占比,所以就有必要尋求其它的解決方案。
第一種方案:
1、首先將手機手機狀態欄透明化:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {//5.0及以上
View decorView = getWindow().getDecorView();
int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
decorView.setSystemUiVisibility(option);
getWindow().setStatusBarColor(Color.TRANSPARENT);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {//4.4到5.0
WindowManager.LayoutParams localLayoutParams = getWindow().getAttributes();
localLayoutParams.flags = (WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS | localLayoutParams.flags);
}
在相應的Activity或基類執行這段代碼就ok了。
可見在4.4到5.0的系統、5.0及以上系統的處理方式有所不同,除了這種代碼修改額方式外,還可以通過主題來修改,需要在values、values-v19、values-v21目錄下分別創建相應的主題:
//values
//values-v19
//values-v21
給相應Activity或Application設置該主題就ok了。
兩種方式根據需求選擇就好了,到這裡我們就完成了第一步,將狀態欄透明化了。
2、給狀態欄著色
完成了第一步,我們開始給狀態欄加上想要的色彩吧!
將狀態欄透明化後,直接運行項目會發現界面布局直接延伸到狀態欄,針對這種情況首先可以在布局文件使用android:fitsSystemWindows="true"屬性讓布局不延伸到狀態欄,接下來添加一個和狀態欄高、寬相同的指定顏色View來覆蓋被透明化的狀態欄,或者使布局的背景顏色為需要的狀態欄顏色。這兩種方式在後邊會說到,這裡我們先看另外一種方式,也是個人比較喜歡的。我們分一下幾種場景來討論:
先做一些准備工作,在values、values-v19目錄添加如下尺寸:
//values
0dp
//values-v19
25dp
關於25dp,在有些系統上可能有誤差,這裡不做討論!
2.1 頁面頂部使用Toolbar(或自定義title)
一般情況狀態欄的顏色和Toolbar的顏色相同,既然狀態欄透明化後,布局頁面延伸到了狀態欄,何不給Toolbar加上一個狀態欄高度的頂部padding呢:
效果如下:
1
至於自定義title的情況經測試也ok的,圖就不貼了,有興趣可看代碼。
2.2、 DrawerLayout + NavigationView + Toolbar
同樣先給Toolbar設置頂部padding,在4.4系統上看下效果:
2
NavigationView竟然沒延伸到狀態欄,好吧,繼續修改,當系統版本小於5.0時,進行如下設置:
private void navViewToTop() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
mDrawerLayout.setFitsSystemWindows(true);
mDrawerLayout.setClipToPadding(false);
}
}
再看效果:
3
2.3、頁面頂部是一張圖片
這種其實是最簡單的,因為狀態欄透明化後,布局已經延伸到狀態,所以不需要其它額外操作:
效果如下:
4
2.4、頁面底部切換Tab + fragment
某些情況下,當我們的頁面采用底部切換Tab + 多個fragment時,可能每個fragment的頂部顏色不一樣。如何實現狀態欄顏色跟隨fragment切換來變化呢?其實原理和2.1類似,這裡我們每個fragment采用自定義的Title,先看FragmentOne的布局:
我們設置Title的背景為橙黃色、同時設置paddingTop,FragmentTwo的布局類似,只是Title的背景為藍色。然後將兩個Fragment添加到Activity中,最後看下切換的效果:
5
嗯,效果還是不錯的,沒有延遲的情況!可惜沒早點發掘這種方式,以前的方案效果略不理想。
第二種方案:
在方案一中,我們沒有使用
android:fitsSystemWindows="true"屬性,而是將布局延伸到狀態欄來處理,這次我們使用
android:fitsSystemWindows="true"屬性,不讓布局延伸到狀態欄,這時狀態欄就是透明的,然後添加一個和狀態欄高、寬相同的指定顏色View來覆蓋被透明化的狀態欄。我們一步步來實現。
1、第一步還是先將狀態欄透明化,方法同上。
2、在布局文件中添加android:fitsSystemWindows="true"屬性:
3、創建View並添加到狀態欄:
private void addStatusBarView() {
View view = new View(this);
view.setBackgroundColor(getResources().getColor(R.color.colorPrimary));
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
getStatusBarHeight(this));
ViewGroup decorView = (ViewGroup) findViewById(android.R.id.content);
decorView.addView(view, params);
}
原理很簡單,但是要額外寫這些代碼。。。最後看下效果:
6
第三種方案:
和方案二類似,同樣使用
android:fitsSystemWindows="true"屬性,再修改布局文件的根布局為需要的狀態欄顏色,因根布局的顏色被修改,所以你需要在裡邊多嵌套一層布局,來指定界面的主背景色,比如白色等等,否則就和狀態欄顏色一樣了。說起來有點抽象,還是看具體的例子吧:
1、先將狀態欄透明化,方法同上。
2、修改布局文件:
修改完了,看效果:
如果項目有幾十個界面,這樣的方式修改起來還是挺累的,你還要考慮各種嵌套問題。
後兩種方案的例子相對簡單,有興趣的話你可以嘗試更多的場景!
三種方式如何選擇,相信到這裡你應該有答案了吧,我個人更喜歡第一種!
如果你有更好的方案,歡迎指點哦!
這幾天在做IM模塊,設計圖要求做一個類似下圖所示的自定義控件。 我百度了一下,發現類似的Ddmo有很多,但是還不能完全滿足設計圖的需求。參考了幾個
今天給大家詳解一下Android中Activity的生命周期,我希望我的講解不像網上大多數文章一樣,基本都是翻譯Android API,過於籠統,相信大家看了,會有一點點
由於我的版本最低是2.2,所以只有把源碼下下來自己改,如果你覺得太多了可自己編譯成jar引用,本人不才,對java不是很熟悉,如果此版本中有錯誤還請大家指出來,此圖顯示的
android 獲取短信驗證碼倒計時public class MainActivity extends Activity {private Button submit;p