Android 基础之统一状态栏与标题栏
Posted Kevin_小飞象
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 基础之统一状态栏与标题栏相关的知识,希望对你有一定的参考价值。
1. 效果图
TitleBar android 标题栏框架,从此布局属性不用记。
- 集成
- 在项目根目录下的 build.gradle 文件中加入
buildscript {
......
}
allprojects {
repositories {
// JitPack 远程仓库:https://jitpack.io
maven { url 'https://jitpack.io' }
}
}
- 在项目 app 模块下的 build.gradle 文件中加入
dependencies {
// 标题栏框架:https://github.com/getActivity/TitleBar
implementation 'com.github.getActivity:TitleBar:8.6'
}
- 统一 TitleBar 样式
/**
* Created on 2021/5/19 17:51
*
* @author Gong Youqiang
*/
public class MyApp extends Application {
@Override
public void onCreate() {
super.onCreate();
// 初始化 TitleBar 默认样式
TitleBar.setDefaultStyle(new LightBarStyle() {
@Override
protected TextView createTextView(Context context) {
return new AppCompatTextView(context);
}
});
}
}
- BaseActivity.java
/**
* Created on 2021/5/12 14:40
*
* @author Gong Youqiang
*/
public abstract class BaseActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStatusBar();
View view = LayoutInflater.from(this).inflate(getLayoutId(), null);
setContentView(view);
ButterKnife.bind(this);
initView();
}
private void setStatusBar() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (isUseFullScreenMode()) {
StatusBarUtil.transparencyBar(this);
} else {
StatusBarUtil.setStatusBarColor(this, getStatusBarColor());
}
if (isUseBlackFontWithStatusBar()) {
StatusBarUtil.setLightStatusBar(this, true, isUseFullScreenMode());
}
}
}
/**
* 是否设置成透明状态栏,即就是全屏模式
*/
protected boolean isUseFullScreenMode() {
return false;
}
/**
* 更改状态栏颜色,只有非全屏模式下有效
*/
protected int getStatusBarColor() {
return R.color.purple_700;
}
/**
* 是否改变状态栏文字颜色为黑色,默认为黑色
*/
protected boolean isUseBlackFontWithStatusBar() {
return true;
}
/**
* 不带参数的跳转
*
* @param clazz 跳转到的目标类
*/
protected void readyGo(final Class<?> clazz) {
Intent intent = new Intent(this, clazz);
startActivity(intent);
}
/**
* 带参数的跳转
*
* @param clazz 跳转到的目标类
* @param bundle 参数
*/
protected void readyGo(final Class<?> clazz, final Bundle bundle) {
Intent intent = new Intent(this, clazz);
if (bundle != null) {
intent.putExtras(bundle);
}
startActivity(intent);
}
/**
* 跳转且返回结果
*
* @param clazz 跳转到的目标类
* @param requestCode 请求码
*/
protected void readyGoForResult(final Class<?> clazz, final int requestCode) {
Intent intent = new Intent(this, clazz);
startActivityForResult(intent, requestCode);
}
/**
* 带参数跳转且返回结果
*
* @param clazz 跳转到的目标类
* @param requestCode 请求码
* @param bundle 参数
*/
protected void readyGoForResult(final Class<?> clazz, final int requestCode, final Bundle bundle) {
Intent intent = new Intent(this, clazz);
if (bundle != null) {
intent.putExtras(bundle);
}
startActivityForResult(intent, requestCode);
}
protected abstract int getLayoutId();
protected abstract void initView();
}
- StatusBarUtil.java
/**
* Created on 2021/5/12 15:44
*
* @author Gong Youqiang
*/
public class StatusBarUtil {
/**
* 修改状态栏为全透明
*/
public static void transparencyBar(Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = activity.getWindow();
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(Color.TRANSPARENT);
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Window window = activity.getWindow();
window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
}
/**
* 修改状态栏颜色
*/
public static void setStatusBarColor(Activity activity, int colorId) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = activity.getWindow();
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(activity.getResources().getColor(colorId));
}
}
/**
* 需要MIUIV6以上
*
* @param dark 是否把状态栏文字及图标颜色设置为深色
* @return boolean 成功执行返回true
*/
private static void MIUISetStatusBarLightMode(Object object, boolean dark) {
Window window = null;
if (object instanceof Activity) {
window = ((Activity) object).getWindow();
} else if (object instanceof Window) {
window = (Window) object;
}
if (window != null) {
Class clazz = window.getClass();
try {
int darkModeFlag;
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);//清除黑色字体
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && RomUtils.isMiUIV7OrAbove()) {
//开发版 7.7.13 及以后版本采用了系统API,旧方法无效但不会报错,所以两个方式都要加上
if (dark) {
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
} else {
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
}
}
} catch (Exception ignore) {
}
}
}
/**
* @param dark true 字体颜色为黑色,false为白色
* @param isFullMode 是否在全屏模式下
*/
public static void setLightStatusBar(final Activity activity, final boolean dark, boolean isFullMode) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (Constant.DEVICE_FIRM == -1) {
Constant.DEVICE_FIRM = RomUtils.getLightStatusBarAvailableRomType();
}
switch (Constant.DEVICE_FIRM) {
case RomUtils.AvailableRomType.MIUI:
MIUISetStatusBarLightMode(activity, dark);
break;
case RomUtils.AvailableRomType.FLYME:
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
setAndroidNativeLightStatusBar(activity, dark, isFullMode);
} else {
setFlymeLightStatusBar(activity, dark);
}
break;
case RomUtils.AvailableRomType.ANDROID_NATIVE:
setAndroidNativeLightStatusBar(activity, dark, isFullMode);
break;
case RomUtils.AvailableRomType.NA:
// N/A do nothing
break;
}
}
}
@RequiresApi(api = Build.VERSION_CODES.M)
public static void setLightStatusBar(final Window window, final boolean dark, boolean isFullMode) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
switch (RomUtils.getLightStatusBarAvailableRomType()) {
case RomUtils.AvailableRomType.MIUI:
MIUISetStatusBarLightMode(window, dark);
break;
case RomUtils.AvailableRomType.FLYME:
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
setAndroidNativeLightStatusBar(window, dark, isFullMode);
} else {
setFlymeLightStatusBar(window, dark);
}
break;
case RomUtils.AvailableRomType.ANDROID_NATIVE:
setAndroidNativeLightStatusBar(window, dark, isFullMode);
break;
case RomUtils.AvailableRomType.NA:
// N/A do nothing
break;
}
}
}
private static boolean setFlymeLightStatusBar(Object obj, boolean dark) {
boolean result = false;
Window window = null;
if (obj instanceof Activity) {
window = ((Activity) obj).getWindow();
} else if (obj instanceof Window) {
window = ((Window) obj);
}
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 ignore) {
}
}
return result;
}
@RequiresApi(api = Build.VERSION_CODES.M)
private static void setAndroidNativeLightStatusBar(Object obj, boolean dark, boolean isFullMode) {
View decor = null;
if (obj instanceof Activity) {
decor = ((Activity) obj).getWindow().getDecorView();
} else if (obj instanceof Window) {
decor = ((Window) obj).getDecorView();
}
if (decor == null) {
return;
}
if (dark) {
if (isFullMode) {
decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
} else {
decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
}
} else {
// We want to change tint color to white again.
// You can also record the flags in advance so that you can turn UI back completely if
// you have set other flags before, such as translucent or full screen.
if (isFullMode) {
decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
} else {
decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
}
}
}
/**
* 获得通知栏高度
*/
public static int getStatusBarHeight(Context context) {
Class<?> c = null;
Object obj = null;
Field field = null;
int x = 0, statusBarHeight = 0;
try {
c = Class.forName("com.android.internal.R$dimen");
obj = c.newInstance();
field = c.getField("status_bar_height");
x = Integer.parseInt(field.get(obj).toString());
statusBarHeight = context.getResources().getDimensionPixelSize(x);
} catch (Exception e1) {
e1.printStackTrace();
}
return statusBarHeight;
}
}
- titel_bar.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center_horizontal"
tools:context=".ui.LoginActivity">
<com.hjq.bar.TitleBar
android:id="@+id/title_bar"
android:layout_width="match_parent"
android:background="@color/purple_500"
带有片段的标题栏与列表视图重叠