主要程式碼
網上資料太多,將這塊的內容也不少,無論是知乎,簡書,還是github上的,這裡只針對我所處理的專案
貼上一下我覺得關鍵的程式碼,處理TRANSLUCENT的,使之成為透明主題,SystemBarTintManager來自SystemBarTint
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_match_actionbar);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
setTranslucentStatus(true);
}
SystemBarTintManager tintManager = new SystemBarTintManager(this);
tintManager.setStatusBarTintEnabled(true);
tintManager.setStatusBarTintResource(R.color.statusbar_bg);
}
@TargetApi(19)
private void setTranslucentStatus(boolean on) {
Window win = getWindow();
WindowManager.LayoutParams winParams = win.getAttributes();
final int bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
if (on) {
winParams.flags |= bits;
} else {
winParams.flags &= ~bits;
}
win.setAttributes(winParams);
}
複製程式碼
設定fitsSystemWindows,讓xml佈局內容位於狀態列之下,當然了這塊的程式碼可以做一下進一步的封裝
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(getLayoutResId());//把設定佈局檔案的操作交給繼承的子類
ViewGroup contentFrameLayout = (ViewGroup) findViewById(Window.ID_ANDROID_CONTENT);
View parentView = contentFrameLayout.getChildAt(0);
if (parentView != null && Build.VERSION.SDK_INT >= 14) {
parentView.setFitsSystemWindows(true);
}
}
複製程式碼
這段程式碼來自AndroidSystemUiTraining 做了一定的封裝,這樣就不需要我們在每個xml的root節點裡面加上android:fitsSystemWindows = 'true'
對於透明主題,我們需要做的就是,修改window的主題,然後修改狀態列顏色值,android4.4的版本稍微特殊,可以通過其他的方式實現修改狀態列的顏色,4.4以下無法修改顏色,5.0以上的可以通過系統api,修改statusBarColor。 修改為了透明主題後,預設情況下,我們的佈局是佔滿全屏區域的,那麼我們的xml佈局是會遮擋住statusbar的(擋住一詞有點不準確,應該說是佔據了statusbar的位置)。
有兩種解決辦法,一種是如上述的程式碼中,設定findViewById(Window.ID_ANDROID_CONTENT).getChildAt(0).setFitsSystemWindows(true)
,這樣強制的讓佈局內容從狀態列下面開始,狀態列以上的顯示的是SystemBarTintManager.setStatusBarTintResource(R.color.statusbar_bg)
設定的顏色
另外一種是不設定setFitsSystemWindows(true)
,xml佈局佔滿全屏,通過一個高度為25dp的view,佔滿狀態列的位置,用paddingTop也可以實現,可以針對具體情況處理,具體可以看知乎上的這篇https://www.zhihu.com/question/31468556,第一個答案
優化後
本文優化後的程式碼主要是這兩種方式混用的,針對不同的頁面採用不同的方案。
//呼叫此方法,當前activity將變成translucent主題,content區域包含全屏,statusBarRes用來設定狀態列顏色值,isFitSystemWindows設定是否需要讓xml佈局內容位於狀態列之下,預設是在狀態列下面
open fun setupStatusBar(@ColorRes statusBarRes: Int, isFitSystemWindows: Boolean = true) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
window.setFlags(
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
SystemBarTintManager(this).apply {
isStatusBarTintEnabled = true
setStatusBarTintResource(statusBarRes)
}
}
if (isFitSystemWindows) {
val contentFrameLayout = findViewById(Window.ID_ANDROID_CONTENT) as ViewGroup
val parentView = contentFrameLayout.getChildAt(0)
if (parentView != null && Build.VERSION.SDK_INT >= 14) {
parentView.fitsSystemWindows = true
}
}
}
複製程式碼
子類只需要重寫這個方法,就可以滿足常見的場景需求了。