版權(quán)聲明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請(qǐng)注明出處+地址
hello,大家好~第一次在簡(jiǎn)書上發(fā)表文章鼎天,如果有什么不對(duì)的地方,大家留言指正蔚叨。
Android 沉浸式狀態(tài)欄 已經(jīng)算是出來比較久的技術(shù)了载绿,只不過我們公司項(xiàng)目最近要優(yōu)化一下UI粥诫,就研究了一下,在此特別感謝簡(jiǎn)書作者揚(yáng)州慢_提供的解決方案崭庸,原文鏈接戳這里怀浆。
言歸正傳,Android沉浸式分為以下幾個(gè)維度去處理
1.API < 19(無法進(jìn)行沉浸式)
2.API = 19(添加與狀態(tài)欄同等寬高的View)
3.API > 19? ?(設(shè)置狀態(tài)欄顏色) 「 API > 22 可以修改狀態(tài)欄的字體和圖標(biāo)顏色冀自,避免因設(shè)置顏色相近看不清狀態(tài)欄原有的字體」
接下來逐條闡明具體解決方案,
(獲取狀態(tài)欄高度以及獲取actionbar的高度的函數(shù)會(huì)在最后給出秒啦,大家先看懂原理)
首先熬粗,對(duì)于API < 19(即安卓4.4系統(tǒng)以下)的沒辦法做處理,而且市場(chǎng)占有率很低余境,可以忽略驻呐;
其次,對(duì)于API = 19(即安卓4.4系統(tǒng))芳来,核心代碼如下:
兩種情況處理:1.有ActionBar(直接調(diào)用系統(tǒng)的才算含末,toolbar不算在這個(gè)分類里面)
? ? ? ? ? ? ? ? ? ? ? ? ?2.沒有ActionBar
//增加占位狀態(tài)欄
ViewGroup decorView = (ViewGroup) mActivity.getWindow().getDecorView();
View statusBarView = new View(activity);
//為statusBarView準(zhǔn)備的布局參數(shù),全屏寬即舌,與狀態(tài)欄一樣的高度
ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(activity));
ViewGroup rootView = mActivity.findViewById(android.R.id.content);
//通過外面設(shè)置是否有actionbar
if (isActionBar()) {
//要增加內(nèi)容視圖的 paddingTop,否則內(nèi)容被 ActionBar 遮蓋
rootView.setPadding(0, getStatusBarHeight(mActivity) + getActionBarHeight(mActivity), 0, 0);
} else {
rootView.setPadding(0, getStatusBarHeight(mActivity), 0, 0);
}
//為占位狀態(tài)欄設(shè)置我們想要的顏色
statusBarView.setBackgroundColor(color);
//為DecorView添加占位狀態(tài)欄
decorView.addView(statusBarView, lp);
以上是代碼邏輯的闡述佣盒,接下來就是針對(duì)API = 19的style的特殊處理(文件路徑 values-v19/styles.xml)
//為你的app的主題加入以下兩個(gè)item
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">false</item>
那么這兩個(gè)屬性是用來干什么的呢?(后續(xù)補(bǔ)充)
最后顽聂,對(duì)于 API > 19(即安卓5.0及以上)肥惭,核心代碼如下:
//直接設(shè)置狀態(tài)欄顏色
Window window = mActivity.getWindow();
//取消設(shè)置透明狀態(tài)欄,使 ContentView 內(nèi)容不再沉浸到狀態(tài)欄下
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
//需要設(shè)置這個(gè) flag 才能調(diào)用 setStatusBarColor 來設(shè)置狀態(tài)欄顏色
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
activity.getWindow().setStatusBarColor(color);
補(bǔ)充,對(duì)于 API > 22(即安卓6.0及以上)紊搪,設(shè)置狀態(tài)欄的字體顏色蜜葱,核心代碼如下:
/** * 設(shè)置狀態(tài)欄文字顏色 bDark為TRUE代表沉浸式 */
private static void setStatusBarMode(Activity activity, boolean bDark) {
? ? //6.0以上
? ? if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
? ? ? ? View decorView = activity.getWindow().getDecorView();
? ? ? ? if (decorView != null) {
? ? ? ? ? ? ? int vis = decorView.getSystemUiVisibility();
? ? ? ? ? ? ? if (bDark) {
????????????????vis |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
????????????????} else {
????????????????vis &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
????????????????}
????????decorView.setSystemUiVisibility(vis);
????????}
????}
}
什么原理呢:?耀石?牵囤??(后續(xù)補(bǔ)充)
getStatusBarHeight獲取狀態(tài)欄高度的函數(shù)如下:
/** * 利用反射獲取狀態(tài)欄高度 */
private static int getStatusBarHeight(Activity activity) {
????????int result = 0; //獲取狀態(tài)欄高度的資源id
????????int resourceId = activity.getResources().getIdentifier("status_bar_height", "dimen", "android");
????????if (resourceId > 0) {
????????????result = activity.getResources().getDimensionPixelSize(resourceId);
? ? ? ?}
????????Log.e("getStatusBarHeight", result + "");
????????return result;
}
getActionBarHeight獲取ActionBar高度的函數(shù)如下:
/** * 獲得 ActionBar 的高度 */
public static int getActionBarHeight(Context context) {
????????int result = 0;
????????if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
? ? ? ? ? ? ? ? TypedValue tv = new TypedValue();
????????????????//劃重點(diǎn)V臀啊=伊邸!0鹉巍P阼搿!之前在4.4手機(jī)上出現(xiàn)了部分UI會(huì)被遮住一點(diǎn)點(diǎn)就是在這里出的問題鉴裹,一定要看你的actionbar用的是哪個(gè)包里面的舞骆,不同包下面大小有些差異
????????????????context.getTheme().resolveAttribute(android.support.v7.appcompat.R.attr.actionBarSize, tv, true);
????????????????result = TypedValue.complexToDimensionPixelSize(tv.data, context.getResources().getDisplayMetrics());
????????}
return result;
}
在設(shè)置沉浸式的同時(shí)钥弯,我們要對(duì)actionbar做去除陰影處理,代碼如下:
/*** 去除 ActionBar 陰影 */
public void clearActionBarShadow() {
????????if (Build.VERSION.SDK_INT >= 21) {
????????????????ActionBar supportActionBar = ((AppCompatActivity) mActivity).getSupportActionBar();
????????????????if (supportActionBar != null) {
????????????????????????supportActionBar.setElevation(0);
? ? ? ? ? ? ? ? }
????????}
????????return this;
}