部分轉載原文地址:https://blog.csdn.net/liup1211/article/details/86583015java
1,本文闡述如何實現沉浸式狀態欄
2,部分代碼有從其餘博客摘抄,也有我本身的總結,若侵犯了原做者的權益,請聯繫我刪除
下面說一下個人實現步驟android
<color name="colorPrimary">#3F424E</color> <color name="colorPrimaryDark">#00000000</color><!--透明--> <color name="colorAccent">#FF4081</color>
<style name="AppTheme" parent="AppTheme.Base"> </style> <style name="AppTheme.Base" parent="Theme.AppCompat.Light.NoActionBar"> <!-- Customize your theme here. --> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/default_bg</item> </style>
<style name="AppTheme" parent="AppTheme.Base"> <!-- Navigation Bar 【false適配某些虛擬按鍵手機】--> <item name="android:windowTranslucentNavigation">false</item> </style>
<application ... ... android:theme="@style/AppTheme" ... ...>
這是重點,若是不設置android:fitsSystemWindows="true",可能會出現部分機型標題欄顯示不全的bugapp
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" app:contentInsetLeft="0dp" app:contentInsetStart="0dp" android:fitsSystemWindows="true" android:background="?attr/colorPrimary"> ... ...
import android.annotation.TargetApi; import android.app.Activity; import android.content.Context; import android.content.res.Resources; import android.os.Build; import android.support.annotation.ColorRes; import android.text.TextUtils; import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; import com.sandy.cloudlock.R; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Properties; public class StatusBarCompatUtil2 { private static final int COLOR_DEFAULT = ResourceUtil.getColor(R.color.colorPrimary); private static int getStatusBarHeight(Context context) { int statusBarHeight = 0; Resources res = context.getResources(); int resourceId = res.getIdentifier("status_bar_height", "dimen", "android"); if (resourceId > 0) { statusBarHeight = res.getDimensionPixelSize(resourceId); } return statusBarHeight; } /** * 設置狀態欄透明 */ public static void setTranslucentStatus(Activity activity, @ColorRes int statusColor) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { Window window = activity.getWindow(); window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE); window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); int color = COLOR_DEFAULT; if (statusColor != 0) { color = ResourceUtil.getColor(statusColor); } window.setStatusBarColor(color); } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { int color = COLOR_DEFAULT; ViewGroup contentView = activity.findViewById(android.R.id.content); if (statusColor != 0) { color = ResourceUtil.getColor(statusColor); } View statusBarView = new View(activity); ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(activity)); statusBarView.setBackgroundColor(color); contentView.addView(statusBarView, lp); } else { activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); } } /** * 改變魅族的狀態欄字體爲黑色,要求FlyMe4以上 */ private static void processFlyme(Activity activity, boolean darkMode) { Window window = activity.getWindow(); if (window != null) { try { WindowManager.LayoutParams lp = window.getAttributes(); Field darkFlag = WindowManager.LayoutParams.class .getDeclaredField("MEIZU_FLAG_DARK_STATUS_BAR_ICON"); Field meizuFlags = WindowManager.LayoutParams.class .getDeclaredField("meizuFlags"); darkFlag.setAccessible(true); meizuFlags.setAccessible(true); int bit = darkFlag.getInt((Object) null); int value = meizuFlags.getInt(lp); if (darkMode) { value |= bit; } else { value &= ~bit; } meizuFlags.setInt(lp, value); window.setAttributes(lp); } catch (Exception var8) { Log.w("StatusBarUtils", "setStatusBarDarkIcon: failed"); } } } /** * 改變小米的狀態欄字體顏色爲黑色, 要求MIUI6以上 lightStatusBar爲真時表示黑色字體 */ private static void processMIUI(Activity activity, boolean darkMode) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { // 即基於 Android 6.0 ,開發版 7.7.13 及之後版本 compatHighMIUI(activity, darkMode); } else { compatLowMIUI(activity, darkMode); } } @TargetApi(Build.VERSION_CODES.M) private static void compatHighMIUI(Activity activity, boolean darkMode) { View decorView = activity.getWindow().getDecorView(); if (darkMode) { decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); } else { int flag = decorView.getSystemUiVisibility() & ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; decorView.setSystemUiVisibility(flag); } } /** * 兼容低版本miui * * @param activity activity * @param darkMode 是否夜間模式 */ private static void compatLowMIUI(Activity activity, boolean darkMode) { Class<? extends Window> clazz = activity.getWindow().getClass(); try { int darkModeFlag = 0; Class<?> layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams"); Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE"); darkModeFlag = field.getInt(layoutParams); Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class); extraFlagField.invoke(activity.getWindow(), darkMode ? darkModeFlag : 0, darkModeFlag); } catch (Exception e) { e.printStackTrace(); } } private static final String KEY_MIUI_VERSION_CODE = "ro.miui.ui.version.code"; private static final String KEY_MIUI_VERSION_NAME = "ro.miui.ui.version.name"; private static final String KEY_MIUI_INTERNAL_STORAGE = "ro.miui.internal.storage"; /** * 判斷手機是不是小米 */ private static boolean isMIUI() { final Properties prop = new Properties(); return prop.getProperty(KEY_MIUI_VERSION_CODE, null) != null || prop.getProperty(KEY_MIUI_VERSION_NAME, null) != null || prop.getProperty(KEY_MIUI_INTERNAL_STORAGE, null) != null; } /** * 判斷手機是不是魅族 * * @return */ private static boolean isFlyme() { try { // Invoke Build.hasSmartBar() final Method method = Build.class.getMethod("hasSmartBar"); return method != null || TextUtils.equals("Meizu", Build.MANUFACTURER); } catch (final Exception e) { return TextUtils.equals("Meizu", Build.MANUFACTURER); } } /** * 設置Android狀態欄的字體顏色,狀態欄爲亮色的時候字體和圖標是黑色,狀態欄爲暗色的時候字體和圖標爲白色 * <p> * 設置狀態欄文字色值爲深色調,默認狀態欄顏色透明(即同標題欄的顏色) * * @param activity activity * @param useDart 是否使用深色調 */ public static void setStatusBarFontIconDark(Activity activity, boolean useDart) { setStatusBarFontIconDark(activity, useDart, 0); } /** * 設置Android狀態欄的字體顏色,狀態欄爲亮色的時候字體和圖標是黑色,狀態欄爲暗色的時候字體和圖標爲白色 * <p> * 設置狀態欄文字色值爲深色調 * * @param activity activity * @param useDart 是否使用深色調 * @param statusColor 自定義的狀態欄顏色 */ public static void setStatusBarFontIconDark(Activity activity, boolean useDart, @ColorRes int statusColor) { if (isMIUI()) { processMIUI(activity, useDart); } else { if (isFlyme()) { processFlyme(activity, useDart); } if (useDart) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { int mode = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; activity.getWindow().getDecorView().setSystemUiVisibility(mode); } } else { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { int mode = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE; activity.getWindow().getDecorView().setSystemUiVisibility(mode); } } activity.getWindow().getDecorView().findViewById(android.R.id.content).setPadding(0, 0, 0, 0); } if (statusColor != 0) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { int color = ResourceUtil.getColor(statusColor); activity.getWindow().setStatusBarColor(color); } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { ViewGroup contentView = activity.findViewById(android.R.id.content); int color = ResourceUtil.getColor(statusColor); View statusBarView = new View(activity); ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(activity)); statusBarView.setBackgroundColor(color); contentView.addView(statusBarView, lp); } } ///適配虛擬按鍵背景色 // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { // activity.getWindow().setNavigationBarColor(COLOR_DEFAULT); // } } }
定義1個activity的超類,在超類的onCreate中調用
setStatusBarFontIconDark(Activity activity, boolean useDart)
狀態欄顏色自定義,調用
setStatusBarFontIconDark(Activity activity, boolean useDart, @ColorRes int statusColor)
如多個fragment切換時,狀態欄顏色不一樣,能夠在fragment的
onActivityCreated (Bundle savedInstanceState)
中調用setStatusBarFontIconDark(Activity activity, boolean useDart, @ColorRes int statusColor)
字體
Rect rectangle = new Rect(); getWindow().getDecorView().getWindowVisibleDisplayFrame(rectangle);//獲取狀態欄高度 ConstraintLayout constraintLayout = findViewById(R.id.constraintLayout);//此ConstraintLayout爲xml根Layout constraintLayout.setPadding(0, rectangle.top,0,0);
此方法無奈之舉ui