先看一下效果图
1.创建一个BarUtils工具类
/**
* 顶部状态栏
*/
public class BarUtils {
private static final int DEFAULT_ALPHA = 112;
private static final String TAG_COLOR = "TAG_COLOR";
private static final String TAG_ALPHA = "TAG_ALPHA";
private static final int TAG_OFFSET = -123;
private BarUtils() {
throw new UnsupportedOperationException("u can't instantiate me...");
}
/**
* 获取状态栏高度(px)
*
* @return 状态栏高度px
*/
public static int getStatusBarHeight(Context context) {
Resources resources = context.getResources();
int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android");
return resources.getDimensionPixelSize(resourceId);
}
/**
* 为view增加MarginTop为状态栏高度
*
* @param view view
*/
public static void addMarginTopEqualStatusBarHeight(@NonNull View view) {
Object haveSetOffset = view.getTag(TAG_OFFSET);
if (haveSetOffset != null && (Boolean) haveSetOffset) return;
ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
// layoutParams.setMargins(layoutParams.leftMargin,
// layoutParams.topMargin + getStatusBarHeight(),
// layoutParams.rightMargin,
// layoutParams.bottomMargin);
view.setTag(TAG_OFFSET, true);
}
/**
* 为view减少MarginTop为状态栏高度
*
* @param view view
*/
public static void subtractMarginTopEqualStatusBarHeight(@NonNull View view) {
Object haveSetOffset = view.getTag(TAG_OFFSET);
if (haveSetOffset == null || !(Boolean) haveSetOffset) return;
ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
// layoutParams.setMargins(layoutParams.leftMargin,
// layoutParams.topMargin - getStatusBarHeight(),
// layoutParams.rightMargin,
// layoutParams.bottomMargin);
view.setTag(TAG_OFFSET, false);
}
/**
* 设置状态栏颜色
*
* @param activity activity
* @param color 状态栏颜色值
*/
public static void setStatusBarColor(@NonNull final Activity activity,
@ColorInt final int color) {
setStatusBarColor(activity, color, DEFAULT_ALPHA, false);
}
/**
* 设置状态栏颜色
*
* @param activity activity
* @param color 状态栏颜色值
* @param alpha 状态栏透明度,此透明度并非颜色中的透明度
*/
public static void setStatusBarColor(@NonNull final Activity activity,
@ColorInt final int color,
@IntRange(from = 0, to = 255) final int alpha) {
setStatusBarColor(activity, color, alpha, false);
}
/**
* 设置状态栏颜色
*
* @param activity activity
* @param color 状态栏颜色值
* @param alpha 状态栏透明度,此透明度并非颜色中的透明度
* @param isDecor {@code true}: 设置在DecorView中<br>
* {@code false}: 设置在ContentView中
*/
public static void setStatusBarColor(@NonNull final Activity activity,
@ColorInt final int color,
@IntRange(from = 0, to = 255) final int alpha,
final boolean isDecor) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return;
hideAlphaView(activity);
transparentStatusBar(activity);
addStatusBarColor(activity, color, alpha, isDecor);
}
/**
* 设置状态栏透明度
*
* @param activity activity
*/
public static void setStatusBarAlpha(@NonNull final Activity activity) {
setStatusBarAlpha(activity, DEFAULT_ALPHA, false);
}
/**
* 设置状态栏透明度
*
* @param activity activity
*/
public static void setStatusBarAlpha(@NonNull final Activity activity,
@IntRange(from = 0, to = 255) final int alpha) {
setStatusBarAlpha(activity, alpha, false);
}
/**
* 设置状态栏透明度
*
* @param activity activity
* @param alpha 状态栏透明度
* @param isDecor {@code true}: 设置在DecorView中<br>
* {@code false}: 设置在ContentView中
*/
public static void setStatusBarAlpha(@NonNull final Activity activity,
@IntRange(from = 0, to = 255) final int alpha,
final boolean isDecor) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return;
hideColorView(activity);
transparentStatusBar(activity);
addStatusBarAlpha(activity, alpha, isDecor);
}
/**
* 设置状态栏颜色
*
* @param fakeStatusBar 伪造状态栏
* @param color 状态栏颜色值
*/
public static void setStatusBarColor(Context context,@NonNull final View fakeStatusBar, @ColorInt final int color) {
setStatusBarColor(context,fakeStatusBar, color, DEFAULT_ALPHA);
}
/**
* 设置状态栏颜色
*
* @param fakeStatusBar 伪造状态栏
* @param color 状态栏颜色值
* @param alpha 状态栏透明度,此透明度并非颜色中的透明度
*/
public static void setStatusBarColor(Context context, final View fakeStatusBar,
@ColorInt final int color,
@IntRange(from = 0, to = 255) final int alpha) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return;
fakeStatusBar.setVisibility(View.VISIBLE);
transparentStatusBar((Activity) fakeStatusBar.getContext());
ViewGroup.LayoutParams layoutParams = fakeStatusBar.getLayoutParams();
layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
layoutParams.height = BarUtils.getStatusBarHeight(context);
fakeStatusBar.setBackgroundColor(getStatusBarColor(color, alpha));
}
/**
* 设置状态栏透明度
*
* @param fakeStatusBar 伪造状态栏
*/
public static void setStatusBarAlpha(@NonNull final View fakeStatusBar) {
setStatusBarAlpha(fakeStatusBar, DEFAULT_ALPHA);
}
/**
* 设置状态栏透明度
*
* @param fakeStatusBar 伪造状态栏
* @param alpha 状态栏透明度
*/
public static void setStatusBarAlpha(@NonNull final View fakeStatusBar,
@IntRange(from = 0, to = 255) final int alpha) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return;
fakeStatusBar.setVisibility(View.VISIBLE);
transparentStatusBar((Activity) fakeStatusBar.getContext());
ViewGroup.LayoutParams layoutParams = fakeStatusBar.getLayoutParams();
layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
// layoutParams.height = BarUtils.getStatusBarHeight();
fakeStatusBar.setBackgroundColor(Color.argb(alpha, 0, 0, 0));
}
/**
* 为DrawerLayout设置状态栏颜色
* <p>DrawLayout需设置 {@code android:fitsSystemWindows="true"}</p>
*
* @param activity activity
* @param drawer drawerLayout
* @param fakeStatusBar 伪造状态栏
* @param color 状态栏颜色值
* @param isTop drawerLayout是否在顶层
*/
public static void setStatusBarColor4Drawer(@NonNull final Activity activity,
@NonNull final DrawerLayout drawer,
@NonNull final View fakeStatusBar,
@ColorInt final int color,
final boolean isTop) {
setStatusBarColor4Drawer(activity, drawer, fakeStatusBar, color, DEFAULT_ALPHA, isTop);
}
/**
* 为DrawerLayout设置状态栏颜色
* <p>DrawLayout需设置 {@code android:fitsSystemWindows="true"}</p>
*
* @param activity activity
* @param drawer drawerLayout
* @param fakeStatusBar 伪造状态栏
* @param color 状态栏颜色值
* @param alpha 状态栏透明度,此透明度并非颜色中的透明度
* @param isTop drawerLayout是否在顶层
*/
public static void setStatusBarColor4Drawer(@NonNull final Activity activity,
@NonNull final DrawerLayout drawer,
@NonNull final View fakeStatusBar,
@ColorInt final int color,
@IntRange(from = 0, to = 255) final int alpha,
final boolean isTop) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return;
drawer.setFitsSystemWindows(false);
transparentStatusBar(activity);
setStatusBarColor(activity,fakeStatusBar, color, isTop ? alpha : 0);
for (int i = 0, len = drawer.getChildCount(); i < len; i++) {
drawer.getChildAt(i).setFitsSystemWindows(false);
}
if (isTop) {
hideAlphaView(activity);
} else {
addStatusBarAlpha(activity, alpha, false);
}
}
/**
* 为DrawerLayout设置状态栏透明度
* <p>DrawLayout需设置 {@code android:fitsSystemWindows="true"}</p>
*
* @param activity activity
* @param drawer drawerLayout
* @param fakeStatusBar 伪造状态栏
* @param isTop drawerLayout是否在顶层
*/
public static void setStatusBarAlpha4Drawer(@NonNull final Activity activity,
@NonNull final DrawerLayout drawer,
@NonNull final View fakeStatusBar,
final boolean isTop) {
setStatusBarAlpha4Drawer(activity, drawer, fakeStatusBar, DEFAULT_ALPHA, isTop);
}
/**
* 为DrawerLayout设置状态栏透明度
* <p>DrawLayout需设置 {@code android:fitsSystemWindows="true"}</p>
*
* @param activity activity
* @param drawer drawerLayout
* @param fakeStatusBar 伪造状态栏
* @param alpha 状态栏透明度
* @param isTop drawerLayout是否在顶层
*/
public static void setStatusBarAlpha4Drawer(@NonNull final Activity activity,
@NonNull final DrawerLayout drawer,
@NonNull final View fakeStatusBar,
@IntRange(from = 0, to = 255) final int alpha,
final boolean isTop) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return;
drawer.setFitsSystemWindows(false);
transparentStatusBar(activity);
setStatusBarAlpha(fakeStatusBar, isTop ? alpha : 0);
for (int i = 0, len = drawer.getChildCount(); i < len; i++) {
drawer.getChildAt(i).setFitsSystemWindows(false);
}
if (isTop) {
hideAlphaView(activity);
} else {
addStatusBarAlpha(activity, alpha, false);
}
}
private static void addStatusBarColor(final Activity activity, final int color, final int alpha, boolean isDecor) {
ViewGroup parent = isDecor ?
(ViewGroup) activity.getWindow().getDecorView() :
(ViewGroup) activity.findViewById(android.R.id.content);
View fakeStatusBarView = parent.findViewWithTag(TAG_COLOR);
if (fakeStatusBarView != null) {
if (fakeStatusBarView.getVisibility() == View.GONE) {
fakeStatusBarView.setVisibility(View.VISIBLE);
}
fakeStatusBarView.setBackgroundColor(getStatusBarColor(color, alpha));
} else {
parent.addView(createColorStatusBarView(parent.getContext(), color, alpha));
}
}
private static void addStatusBarAlpha(final Activity activity, final int alpha, boolean isDecor) {
ViewGroup parent = isDecor ?
(ViewGroup) activity.getWindow().getDecorView() :
(ViewGroup) activity.findViewById(android.R.id.content);
View fakeStatusBarView = parent.findViewWithTag(TAG_ALPHA);
if (fakeStatusBarView != null) {
if (fakeStatusBarView.getVisibility() == View.GONE) {
fakeStatusBarView.setVisibility(View.VISIBLE);
}
fakeStatusBarView.setBackgroundColor(Color.argb(alpha, 0, 0, 0));
} else {
parent.addView(createAlphaStatusBarView(parent.getContext(), alpha));
}
}
private static void hideColorView(final Activity activity) {
ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
View fakeStatusBarView = decorView.findViewWithTag(TAG_COLOR);
if (fakeStatusBarView == null) return;
fakeStatusBarView.setVisibility(View.GONE);
}
private static void hideAlphaView(final Activity activity) {
ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
View fakeStatusBarView = decorView.findViewWithTag(TAG_ALPHA);
if (fakeStatusBarView == null) return;
fakeStatusBarView.setVisibility(View.GONE);
}
private static int getStatusBarColor(final int color, final int alpha) {
if (alpha == 0) return color;
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 Color.argb(255, red, green, blue);
}
/**
* 绘制一个和状态栏一样高的颜色矩形
*/
private static View createColorStatusBarView(final Context context, final int color, final int alpha) {
View statusBarView = new View(context);
statusBarView.setLayoutParams(new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(context)));
statusBarView.setBackgroundColor(getStatusBarColor(color, alpha));
statusBarView.setTag(TAG_COLOR);
return statusBarView;
}
/**
* 绘制一个和状态栏一样高的黑色透明度矩形
*/
private static View createAlphaStatusBarView(final Context context, final int alpha) {
View statusBarView = new View(context);
statusBarView.setLayoutParams(new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(context)));
statusBarView.setBackgroundColor(Color.argb(alpha, 0, 0, 0));
statusBarView.setTag(TAG_ALPHA);
return statusBarView;
}
private static void transparentStatusBar(final Activity activity) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return;
Window window = activity.getWindow();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
int option = View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
window.getDecorView().setSystemUiVisibility(option);
window.setStatusBarColor(Color.TRANSPARENT);
} else {
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
}
///
// action bar
///
/**
* 获取ActionBar高度
*
* @param activity activity
* @return ActionBar高度
*/
public static int getActionBarHeight(@NonNull final Activity activity) {
TypedValue tv = new TypedValue();
if (activity.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
return TypedValue.complexToDimensionPixelSize(tv.data, activity.getResources().getDisplayMetrics());
}
return 0;
}
///
// notification bar
///
/**
* 显示通知栏
* <p>需添加权限 {@code <uses-permission android:name="android.permission.EXPAND_STATUS_BAR"/>}</p>
*
* @param context 上下文
* @param isSettingPanel {@code true}: 打开设置<br>{@code false}: 打开通知
*/
public static void showNotificationBar(@NonNull final Context context, final boolean isSettingPanel) {
String methodName = (Build.VERSION.SDK_INT <= 16) ? "expand"
: (isSettingPanel ? "expandSettingsPanel" : "expandNotificationsPanel");
invokePanels(context, methodName);
}
/**
* 隐藏通知栏
* <p>需添加权限 {@code <uses-permission android:name="android.permission.EXPAND_STATUS_BAR"/>}</p>
*
* @param context 上下文
*/
public static void hideNotificationBar(@NonNull final Context context) {
String methodName = (Build.VERSION.SDK_INT <= 16) ? "collapse" : "collapsePanels";
invokePanels(context, methodName);
}
/**
* 反射唤醒通知栏
*
* @param context 上下文
* @param methodName 方法名
*/
private static void invokePanels(@NonNull final Context context, final String methodName) {
try {
Object service = context.getSystemService("statusbar");
Class<?> statusBarManager = Class.forName("android.app.StatusBarManager");
Method expand = statusBarManager.getMethod(methodName);
expand.invoke(service);
} catch (Exception e) {
e.printStackTrace();
}
}
///
// navigation bar
///
/**
* 获取导航栏高度
* <p>0代表不存在</p>
*
* @return 导航栏高度
*/
public static int getNavBarHeight(Context context) {
Resources res = context.getResources();
int resourceId = res.getIdentifier("navigation_bar_height", "dimen", "android");
if (resourceId != 0) {
return res.getDimensionPixelSize(resourceId);
} else {
return 0;
}
}
/**
* 隐藏导航栏
*
* @param activity activity
*/
public static void hideNavBar(@NonNull final Activity activity) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) return;
if (getNavBarHeight(activity) > 0) {
View decorView = activity.getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
decorView.setSystemUiVisibility(uiOptions);
}
}
}
2.创建BaseActivity
public class BaseActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_base);
View fakeStatusBar = findViewById(R.id.fake_status_bar);
BarUtils.setStatusBarColor(this, fakeStatusBar, Color.WHITE);
}
}
3.activity_base 布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<View
android:id="@+id/fake_status_bar"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="@android:color/transparent"/>
</LinearLayout>
4.MainActivity 继承 BaseActivity
public class MainActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
5.activity_main 布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context=".MainActivity"
android:background="#0ff">
</RelativeLayout>
6.values文件夹——styles文件
在ActionBar前面加No
<resources>
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
.....
</style>
</resources>
这样就大功告成了,但是状态栏会跟顶部布局重叠。
解决此问题的办法写在另一篇博客中了
点击 > 布局顶部与状态栏重叠