沉浸式出现
- Android4.4 ( KITKAT = 19)版本出现的
- 可以给状态栏设置颜色window.setStatusBarColor(Color.TRANSPARENT)
- 但是5.0设置透明的时候,有些机型会出现黑色,如果你是通栏的情况不会通栏,设置 window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);api上说清掉不透明度window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);但是6.0机型才出现改变状态栏里面字体和图标颜色,如果你是白色背景就不要在6.0以前清掉状态栏不透明度
- 6.0提供了修改状态栏字体和图标颜色(默认白色,添加这些设置改成黑色)getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);但是小米和魅族不兼容,做了自己的适配,所以需要兼容下机型,但是自己的机型有些也没适配成功,所以这个最好还是加上;
沉浸式页面,使用EditText出现顶出状态栏bug
public class KeyBoardListen {
private int scrollHeight;
private int heightDifference;
/**
* @param lilayContent 想要滑动的布局
* @param edt
* @param activity
*/
public void listen(ViewGroup lilayContent, EditText edt, Activity activity) {
//View树变动回调
lilayContent.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
if (edt.isFocused()) {
Rect r = new Rect();
//获取当前界面可视部分
activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(r);
//获取屏幕的高度
int screenHeight = activity.getWindow().getDecorView().getRootView().getHeight();
//此处就是用来获取键盘的高度的, 在键盘没有弹出的时候 此高度为0 键盘弹出的时候为一个正数
heightDifference = screenHeight - r.bottom;
if (heightDifference > 200) {
int[] location = new int[2];
edt.getLocationOnScreen(location);
scrollHeight = location[1] + heightDifference + edt.getHeight() - screenHeight;
lilayContent.scrollBy(0, scrollHeight);
} else {
if (scrollHeight != 0)
lilayContent.scrollBy(0, -scrollHeight);
scrollHeight = 0;
}
}
});
}
}
字体图标工具类
public class ObtainMobile {
private static final String SYS_EMUI = "sys_emui";
private static final String SYS_MIUI = "sys_miui";
private static final String SYS_FLYME = "sys_flyme";
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 final String KEY_EMUI_API_LEVEL = "ro.build.hw_emui_api_level";
private static final String KEY_EMUI_VERSION = "ro.build.version.emui";
private static final String KEY_EMUI_CONFIG_HW_SYS_VERSION = "ro.confg.hw_systemversion";
public static String system = null;
/**
* 设置成黑色
* 修改状态栏字体颜色(6.0以下不起效果,不能直接设置,而是通过两种模式,魅族、小米有对应暴露方法,但本文得考虑所有机型)
*
* @param activity
*/
public static void StatusBarLightMode(Activity activity) {
if (system == null||"".equals(system)) {
system = getSystem();
}
if (system.equals(SYS_MIUI)) {
MIUISetStatusBarLightMode(activity.getWindow(), true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
} else if (system.equals(SYS_FLYME)) {
FlymeSetStatusBarLightMode(activity.getWindow(), true);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
}else {
}
}
public static String getSystem() {
String SYS = "";
try {
Properties prop = new Properties();
prop.load(new FileInputStream(new File(Environment.getRootDirectory(), "build.prop")));
if (prop.getProperty(KEY_MIUI_VERSION_CODE, null) != null
|| prop.getProperty(KEY_MIUI_VERSION_NAME, null) != null
|| prop.getProperty(KEY_MIUI_INTERNAL_STORAGE, null) != null) {
SYS = SYS_MIUI;//小米
} else if (prop.getProperty(KEY_EMUI_API_LEVEL, null) != null
|| prop.getProperty(KEY_EMUI_VERSION, null) != null
|| prop.getProperty(KEY_EMUI_CONFIG_HW_SYS_VERSION, null) != null) {
SYS = SYS_EMUI;//华为
} else if (getMeizuFlymeOSFlag().toLowerCase().contains("flyme")) {
SYS = SYS_FLYME;//魅族
}
} catch (IOException e) {
// e.printStackTrace();
return SYS;
}
return SYS;
}
private static String getMeizuFlymeOSFlag() {
return getSystemProperty("ro.build.display.id", "");
}
private static String getSystemProperty(String key, String defaultValue) {
try {
Class> clz = Class.forName("android.os.SystemProperties");
Method get = clz.getMethod("get", String.class, String.class);
return (String) get.invoke(clz, key, defaultValue);
} catch (Exception e) {
}
return defaultValue;
}
/**
* 设置状态栏图标为深色和魅族特定的文字风格
* 可以用来判断是否为Flyme用户
*
* @param window 需要设置的窗口
* @param dark 是否把状态栏字体及图标颜色设置为深色
* @return boolean 成功执行返回true
*/
private static boolean FlymeSetStatusBarLightMode(Window window, boolean dark) {
boolean result = false;
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(null);
int value = meizuFlags.getInt(lp);
if (dark) {
value |= bit;
} else {
value &= ~bit;
}
meizuFlags.setInt(lp, value);
window.setAttributes(lp);
result = true;
} catch (Exception e) {
}
}
return result;
}
/**
* 设置状态栏字体图标为深色,需要MIUIV6以上
*
* @param window 需要设置的窗口
* @param dark 是否把状态栏字体及图标颜色设置为深色
* @return boolean 成功执行返回true
*/
private static boolean MIUISetStatusBarLightMode(Window window, boolean dark) {
boolean result = false;
if (window != null) {
Class clazz = window.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);
if (dark) {
extraFlagField.invoke(window, darkModeFlag, darkModeFlag);//状态栏透明且黑色字体
} else {
extraFlagField.invoke(window, 0, darkModeFlag);//清除黑色字体
}
result = true;
} catch (Exception e) {
result = false;
}
}
return result;
}
}
状态栏工具类
public class StatusBarCompat {
private static final int COLOR_TRANSLUCENT = Color.TRANSPARENT;
public static final int DEFAULT_COLOR_ALPHA = 112;
/**
* set statusBarColor
*
* @param statusColor color
* @param alpha 0 - 255
*/
public static void setStatusBarColor(Activity activity, int statusColor, int alpha) {
setStatusBarColor(activity, calculateStatusBarColor(statusColor, alpha));
}
public static void setStatusBarColor(Activity activity, int statusColor) {
Window window = activity.getWindow();
ViewGroup mContentView = (ViewGroup) activity.findViewById(Window.ID_ANDROID_CONTENT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
View decorView = activity.getWindow().getDecorView();
int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
decorView.setSystemUiVisibility(option);
activity.getWindow().setStatusBarColor(statusColor);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
//After LOLLIPOP not translucent status bar
// window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
//Then call setStatusBarColor.
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(statusColor);
//set child View not fill the system window
View mChildView = mContentView.getChildAt(0);
if (mChildView != null) {
ViewCompat.setFitsSystemWindows(mChildView, true);
}
} else {
//First translucent status bar.
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
ViewGroup mDecorView = (ViewGroup) window.getDecorView();
if (mDecorView.getTag() != null && mDecorView.getTag() instanceof Boolean && (Boolean) mDecorView.getTag()) {
//if has add fake status bar view
View mStatusBarView = mDecorView.getChildAt(0);
if (mStatusBarView != null) {
mStatusBarView.setBackgroundColor(statusColor);
}
} else {
int statusBarHeight = getStatusBarHeight(activity);
//add margin
View mContentChild = mContentView.getChildAt(0);
if (mContentChild != null) {
ViewCompat.setFitsSystemWindows(mContentChild, false);
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mContentChild.getLayoutParams();
lp.topMargin += statusBarHeight;
mContentChild.setLayoutParams(lp);
}
//add fake status bar view
View mStatusBarView = new View(activity);
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, statusBarHeight);
layoutParams.gravity = Gravity.TOP;
mStatusBarView.setLayoutParams(layoutParams);
mStatusBarView.setBackgroundColor(statusColor);
mDecorView.addView(mStatusBarView, 0);
mDecorView.setTag(true);
}
}
}
}
public static void translucentStatusBar(Activity activity) {
translucentStatusBar(activity, true);
}
/**
* change to full screen mode
*
* @param hideStatusBarBackground hide status bar alpha Background when SDK > 21, true if hide it
*/
public static void translucentStatusBar(Activity activity, boolean hideStatusBarBackground) {
Window window = activity.getWindow();
ViewGroup mContentView = (ViewGroup) activity.findViewById(Window.ID_ANDROID_CONTENT);
//set child View not fill the system window
View mChildView = mContentView.getChildAt(0);
if (mChildView != null) {
ViewCompat.setFitsSystemWindows(mChildView, false);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.setStatusBarColor(COLOR_TRANSLUCENT);
if (mChildView != null) {
ViewCompat.requestApplyInsets(mChildView);
}
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
int statusBarHeight = getStatusBarHeight(activity);
//First translucent status bar. //5.0上加的属性
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
//After LOLLIPOP just set LayoutParams.
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
if (hideStatusBarBackground) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.setStatusBarColor(COLOR_TRANSLUCENT);
} else {
window.setStatusBarColor(COLOR_TRANSLUCENT);
}
//must call requestApplyInsets, otherwise it will have space in screen bottom
if (mChildView != null) {
ViewCompat.requestApplyInsets(mChildView);
}
} else {
ViewGroup mDecorView = (ViewGroup) window.getDecorView();
if (mDecorView.getTag() != null && mDecorView.getTag() instanceof Boolean && (Boolean) mDecorView.getTag()) {
mChildView = mDecorView.getChildAt(0);
//remove fake status bar view.
mContentView.removeView(mChildView);
mChildView = mContentView.getChildAt(0);
if (mChildView != null) {
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mChildView.getLayoutParams();
//cancel the margin top
if (lp != null && lp.topMargin >= statusBarHeight) {
lp.topMargin -= statusBarHeight;
mChildView.setLayoutParams(lp);
}
}
mDecorView.setTag(false);
}
}
}
}
//Get status bar height
public static int getStatusBarHeight(Context context) {
int result = 0;
int resId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resId > 0) {
result = context.getResources().getDimensionPixelOffset(resId);
}
return result;
}
//Get alpha color
private static int calculateStatusBarColor(int color, int alpha) {
float a = 1 - alpha / 255f;
int red = color >> 16 & 0xff;
int green = color >> 8 & 0xff;
int blue = color & 0xff;
red = (int) (red * a + 0.5);
green = (int) (green * a + 0.5);
blue = (int) (blue * a + 0.5);
return 0xff << 24 | red << 16 | green << 8 | blue;
}
}