Recently, I met a personalized requirement in the development, which is similar to the realization of the gradual status bar on the top of QQ, as shown in the following figure
On Android5.0, the system API allows you to directly set the StatusBar to change the color of the StatusBar. On android 4.4, however, the basic principle for changing the color of the StatusBar is to make the StatusBar itself transparent. Then add a View of the same size in the StatusBar position and color it. We have to make a gradient color status bar that is compatible with the differences between the upper and lower versions
For more information about the immersive status bar, see Hongyang Dashen’s article
Let your status bar change color
Solid color compatible status bar
/** * set the status bar color ** @param activity Specifies the activity * @param color status bar color * @param statusBarAlpha status bar transparency */ public static voidsetColor(Activity activity, @ColorInt int color, @IntRange(from = 0, to = 255) int statusBarAlpha) {
if(build.version.sdk_int >= build.version_codes.lollipop) {// Higher than 5.0 // Can be called only by setting flag_drawS_system_bar_BACKGROUNDsetStatusBarColor methods to set the status bar color activity. GetWindow () addFlags (WindowManager. LayoutParams. FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); / / set FLAG_TRANSLUCENT_STATUS transparent status bar activity. GetWindow (). ClearFlags (WindowManager. LayoutParams. FLAG_TRANSLUCENT_STATUS); // Display activity.getwindow ().setStatusBarColor(calculateStatusColor(color, statusBarAlpha)) based on the entered color and transparency; }else if(build.version.sdk_int >= build.version_codes.kitkat) {// Lower VERSION // Add transparent status bar activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); ViewGroup decorView = (ViewGroup) activity.getwindow ().getDecorView(); // Get the top StatusBarView, customize the Id of the StatusBarView (create Id in resources) View fakeStatusBarView = decorView.findViewById(R.id.statusbarutil_fake_status_bar_view);if(fakeStatusBarView ! = null) {if(fakeStatusBarView.getVisibility() == View.GONE) { fakeStatusBarView.setVisibility(View.VISIBLE); } / / set the top color fakeStatusBarView. SetBackgroundColor (calculateStatusColor (color, statusBarAlpha)); }elseDecorviet. addView(createStatusBarView(Activity, color, statusBarAlpha)); }setRootView(activity); }}Copy the code
CalculateStatusColor (Calculate status bar color)
/** * Calculate the status bar color ** @param color color value * @param alpha alpha value * @return*/ private static int calculateStatusColor(@colorint int color, 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 0xff << 24 | red << 16 | green << 8 | blue;
}
Copy the code
Custom View status bar
/** * custom View status bar ** @param activity Required to set the activity * @param color status bar color * @param alpha transparent value * @return*/ private static View createStatusBarView(Activity Activity, @colorInt int color, View statusBarView = new View(Activity); // Draw a rectangle with the same height as the status bar. LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(activity)); statusBarView.setLayoutParams(params); statusBarView.setBackgroundColor(calculateStatusColor(color, alpha)); SetId (FAKE_STATUS_BAR_VIEW_ID); // The default StatusBarView Id is statusbarview. setId(FAKE_STATUS_BAR_VIEW_ID);return statusBarView;
}
Copy the code
Finally, redesign the layout
setRootView
/** * Sets the root layout parameter */ private static voidsetRootView(Activity Activity) {//ViewGroup parent = (ViewGroup) activity.findViewById(android.R.id.content);for (int i = 0, count = parent.getChildCount(); i < count; i++) {
View childView = parent.getChildAt(i);
if (childView instanceof ViewGroup) {
childView.setFitsSystemWindows(true);
((ViewGroup) childView).setClipToPadding(true); }}}Copy the code
The basic configuration of the solid color status bar is ok. Just create the Utils utility class to call in the Activity.
// Set the solid-color status bar statusBarutil.setcolor (this, apputils.getColor (r.color.colorPrimary));Copy the code
Gradient compatible status bar
The following code
/** * @param Activity Specifies the activity to be set. * @param statusBarAlpha specifies the status bar transparency. * @param needOffsetView specifies the downward offset View public static voidsetTranslucentForWindow(Activity activity, @IntRange(from = 0, to = 255) int statusBarAlpha,
View needOffsetView) {
if(build.version.sdk_int > build.version_codes.kitkat) {// VERSION 5.0 or latersetTransparentForWindow(activity);
addTranslucentView(activity, statusBarAlpha);
if(needOffsetView ! = null) { Object haveSetOffset = needOffsetView.getTag(TAG_KEY_HAVE_SET_OFFSET);if(haveSetOffset ! = null && (Boolean) haveSetOffset) {return;
}
ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) needOffsetView.getLayoutParams();
layoutParams.setMargins(layoutParams.leftMargin, layoutParams.topMargin + getStatusBarHeight(activity),
layoutParams.rightMargin, layoutParams.bottomMargin);
needOffsetView.setTag(TAG_KEY_HAVE_SET_OFFSET, true); }}else{/ / / / low version status bar activity. The transparent getWindow () addFlags (WindowManager. LayoutParams. FLAG_TRANSLUCENT_STATUS); ViewGroup decorView = (ViewGroup) activity.getwindow ().getDecorView(); FakeStatusBarView = decorView.findViewById(FAKE_STATUS_BAR_VIEW_ID);if(fakeStatusBarView ! = null) {if(fakeStatusBarView.getVisibility() == View.GONE) { fakeStatusBarView.setVisibility(View.VISIBLE); } / / set the top color fakeStatusBarView. SetBackgroundResource (R.d rawable. Shape_gradient); }elseView statusBarView = new View(activity); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(activity)); statusBarView.setLayoutParams(params); fakeStatusBarView.setBackgroundResource(R.drawable.shape_gradient); statusBarView.setId(FAKE_STATUS_BAR_VIEW_ID); decorView.addView(statusBarView); }setRootView(activity); }}Copy the code
getStatusBarHeight
/** * get the status bar height ** @param context context * @returnStatus bar height */ public static int getStatusBarHeight(Context Context) {// getStatusBarHeight int resourceId = context.getResources().getIdentifier("status_bar_height"."dimen"."android");
return context.getResources().getDimensionPixelSize(resourceId);
}
Copy the code
setTransparentForWindow
/** * transparent */ public static voidsetTransparentForWindow(Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
activity.getWindow()
.getDecorView()
.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
activity.getWindow()
.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
Copy the code
addTranslucentView
/** * add a translucent rectangle ** @param Activity To set the activity * @param statusBarAlpha transparent value */ private static void addTranslucentView(Activity activity, @IntRange(from = 0, to = 255) int statusBarAlpha) { ViewGroup contentView = (ViewGroup) activity.findViewById(android.R.id.content); FakeTranslucentView = contentView.findViewById(FAKE_TRANSLUCENT_VIEW_ID);if(fakeTranslucentView ! = null) {if (fakeTranslucentView.getVisibility() == View.GONE) {
fakeTranslucentView.setVisibility(View.VISIBLE);
}
fakeTranslucentView.setBackgroundColor(Color.argb(statusBarAlpha, 0, 0, 0));
} else{ contentView.addView(createTranslucentStatusBarView(activity, statusBarAlpha)); }}Copy the code
To set the status bar for this gradient color, simply pass in the Toolbar as a View, called as follows
/ / set the gradient color status bar StatusBarUtil. SetTransparentForWindow (this, mToolbar); // The layout is like <? 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"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/shape_gradient"
android:theme="@style/AppTheme.AppBarOverlay"
app:elevation="@dimen/dp0">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="? attr/actionBarSize"
app:popupTheme="@style/ToolbarPopupTheme"
app:title="@string/main_toolbar_title_top"
app:titleTextColor="@color/colorPrimary">
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
</LinearLayout>
Copy the code
Demo Link
At this point, the configuration of the gradient status bar is completely covered