安卓沉浸式状态栏
实现Activity嵌套fragment,不同fragment顶部实现不同的效果(图片沉浸状态栏,设置不同颜色的状态栏)
效果图
- 首先在Activity的onCreate(Bundle savedInstanceState)方法中setContentView(R.layout.xxx)下面设置动态显示隐藏状态栏
if (Build.VERSION. SDK_INT >= 21) {
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);//状态栏透明
}
/* setSystemUiVisibility(int visibility) 动态显示隐藏状态栏
* View.SYSTEM_UI_FLAG_FULLSCREEN 全屏显示并隐藏状态栏
* View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 全屏显示布局不占用状态栏空间,状态栏正常显示,activity顶部布局被状态栏遮住
* */
2.上面设置会导致顶部布局被状态栏遮挡住,所以我们需要写一个View,高度等于状态栏的高度,将布局标题显示出来
在具体xml中加入下面代码
<!--android:background="@color/colorAccent"根据具体自己需要的标题栏颜色去进行设置,
若顶部是图片则不需要加背景-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="@+id/ll_title"
android:background="@color/colorAccent"
>
<View
android:id="@+id/status_bar"
android:layout_width="match_parent"
android:layout_height="0dp"
/>
</LinearLayout>
并通过java代码获取状态栏高度
View view = inflater.inflate(R.layout.fragment_first, container, false);
View mStateBar = view.findViewById( R.id.status_bar);
mStateBar.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,StatusBarUtil.getStatusBarHeight(getActivity())));//填充状态栏
/*StatusBarUtil.getStatusBarHeight(getActivity())获取状态栏高度*/
工具类
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.os.Build;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import androidx.annotation.IntDef;
public class StatusBarUtil {
public final static int TYPE_MIUI = 0;
public final static int TYPE_FLYME = 1;
public final static int TYPE_M = 3;//6.0
@IntDef({TYPE_MIUI,
TYPE_FLYME,
TYPE_M})
@Retention(RetentionPolicy.SOURCE)
@interface ViewType {
}
/**
* 设置状态栏深色浅色切换
*/
public static boolean setStatusBarDarkTheme(Activity activity, boolean dark) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
setStatusBarFontIconDark(activity, TYPE_M, dark);
} else if (OSUtils.isMiui()) {
setStatusBarFontIconDark(activity, TYPE_MIUI, dark);
} else if (OSUtils.isFlyme()) {
setStatusBarFontIconDark(activity, TYPE_FLYME, dark);
} else {//其他情况
return false;
}
return true;
}
return false;
}
/**
* 设置 状态栏深色浅色切换
*/
public static boolean setStatusBarFontIconDark(Activity activity, @ViewType int type,boolean dark) {
switch (type) {
case TYPE_MIUI:
return setMiuiUI(activity, dark);
case TYPE_FLYME:
return setFlymeUI(activity, dark);
case TYPE_M:
default:
return setCommonUI(activity,dark);
}
}
//设置6.0 状态栏深色浅色切换
public static boolean setCommonUI(Activity activity, boolean dark) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
View decorView = activity.getWindow().getDecorView();
if (decorView != null) {
int vis = decorView.getSystemUiVisibility();
if (dark) {
vis |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
} else {
vis &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
}
if (decorView.getSystemUiVisibility() != vis) {
decorView.setSystemUiVisibility(vis);
}
return true;
}
}
return false;
}
//设置Flyme 状态栏深色浅色切换
public static boolean setFlymeUI(Activity activity, boolean dark) {
try {
Window window = activity.getWindow();
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(null);
int value = meizuFlags.getInt(lp);
if (dark) {
value |= bit;
} else {
value &= ~bit;
}
meizuFlags.setInt(lp, value);
window.setAttributes(lp);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
//设置MIUI 状态栏深色浅色切换
public static boolean setMiuiUI(Activity activity, boolean dark) {
try {
Window window = activity.getWindow();
Class<?> clazz = activity.getWindow().getClass();
@SuppressLint("PrivateApi") Class<?> layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams");
Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE");
int darkModeFlag = field.getInt(layoutParams);
Method extraFlagField = clazz.getDeclaredMethod("setExtraFlags", int.class, int.class);
extraFlagField.setAccessible(true);
if (dark) { //状态栏亮色且黑色字体
extraFlagField.invoke(window, darkModeFlag, darkModeFlag);
} else {
extraFlagField.invoke(window, 0, darkModeFlag);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
//获取状态栏高度
public static int getStatusBarHeight(Context context) {
int result = 0;
int resourceId = context.getResources().getIdentifier(
"status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = context.getResources().getDimensionPixelSize(resourceId);
}
return result;
}
}
状态栏默认字体是白色,我们可以在Activiy当中点击切换不同fragment中设置白色 黑色字体切换
switch (getmDefaultShow) {
case first:
StatusBarUtil.setStatusBarDarkTheme(this, false);
break;
case second:
StatusBarUtil.setStatusBarDarkTheme(this, false);
break;
case third:
StatusBarUtil.setStatusBarDarkTheme(this, false);
break;
case forth:
//黑色字体
StatusBarUtil.setStatusBarDarkTheme(this, true);
break;
}