|
@@ -0,0 +1,218 @@
|
|
|
|
|
+package com.sheep.gamegroup.util.statusbar;
|
|
|
|
|
+
|
|
|
|
|
+import android.annotation.TargetApi;
|
|
|
|
|
+import android.app.Activity;
|
|
|
|
|
+import android.content.Context;
|
|
|
|
|
+import android.os.Build;
|
|
|
|
|
+import android.support.design.widget.AppBarLayout;
|
|
|
|
|
+import android.support.design.widget.CollapsingToolbarLayout;
|
|
|
|
|
+import android.support.design.widget.CoordinatorLayout;
|
|
|
|
|
+import android.support.v4.view.ViewCompat;
|
|
|
|
|
+import android.support.v7.widget.Toolbar;
|
|
|
|
|
+import android.view.Gravity;
|
|
|
|
|
+import android.view.View;
|
|
|
|
|
+import android.view.ViewGroup;
|
|
|
|
|
+import android.view.Window;
|
|
|
|
|
+import android.view.WindowManager;
|
|
|
|
|
+import android.widget.FrameLayout;
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * After kitkat add fake status bar
|
|
|
|
|
+ * Created by qiu on 8/27/16.
|
|
|
|
|
+ */
|
|
|
|
|
+@TargetApi(Build.VERSION_CODES.KITKAT)
|
|
|
|
|
+class StatusBarCompatKitKat {
|
|
|
|
|
+
|
|
|
|
|
+ private static final String TAG_FAKE_STATUS_BAR_VIEW = "statusBarView";
|
|
|
|
|
+ private static final String TAG_MARGIN_ADDED = "marginAdded";
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * return statusBar's Height in pixels
|
|
|
|
|
+ */
|
|
|
|
|
+ private 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;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 1. Add fake statusBarView.
|
|
|
|
|
+ * 2. set tag to statusBarView.
|
|
|
|
|
+ */
|
|
|
|
|
+ private static View addFakeStatusBarView(Activity activity, int statusBarColor, int statusBarHeight) {
|
|
|
|
|
+ Window window = activity.getWindow();
|
|
|
|
|
+ ViewGroup mDecorView = (ViewGroup) window.getDecorView();
|
|
|
|
|
+
|
|
|
|
|
+ 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(statusBarColor);
|
|
|
|
|
+ mStatusBarView.setTag(TAG_FAKE_STATUS_BAR_VIEW);
|
|
|
|
|
+
|
|
|
|
|
+ mDecorView.addView(mStatusBarView);
|
|
|
|
|
+ return mStatusBarView;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * use reserved order to remove is more quickly.
|
|
|
|
|
+ */
|
|
|
|
|
+ private static void removeFakeStatusBarViewIfExist(Activity activity) {
|
|
|
|
|
+ Window window = activity.getWindow();
|
|
|
|
|
+ ViewGroup mDecorView = (ViewGroup) window.getDecorView();
|
|
|
|
|
+
|
|
|
|
|
+ View fakeView = mDecorView.findViewWithTag(TAG_FAKE_STATUS_BAR_VIEW);
|
|
|
|
|
+ if (fakeView != null) {
|
|
|
|
|
+ mDecorView.removeView(fakeView);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * add marginTop to simulate set FitsSystemWindow true
|
|
|
|
|
+ */
|
|
|
|
|
+ private static void addMarginTopToContentChild(View mContentChild, int statusBarHeight) {
|
|
|
|
|
+ if (mContentChild == null) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!TAG_MARGIN_ADDED.equals(mContentChild.getTag())) {
|
|
|
|
|
+ FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mContentChild.getLayoutParams();
|
|
|
|
|
+ lp.topMargin += statusBarHeight;
|
|
|
|
|
+ mContentChild.setLayoutParams(lp);
|
|
|
|
|
+ mContentChild.setTag(TAG_MARGIN_ADDED);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * remove marginTop to simulate set FitsSystemWindow false
|
|
|
|
|
+ */
|
|
|
|
|
+ private static void removeMarginTopOfContentChild(View mContentChild, int statusBarHeight) {
|
|
|
|
|
+ if (mContentChild == null) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (TAG_MARGIN_ADDED.equals(mContentChild.getTag())) {
|
|
|
|
|
+ FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mContentChild.getLayoutParams();
|
|
|
|
|
+ lp.topMargin -= statusBarHeight;
|
|
|
|
|
+ mContentChild.setLayoutParams(lp);
|
|
|
|
|
+ mContentChild.setTag(null);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * set StatusBarColor
|
|
|
|
|
+ *
|
|
|
|
|
+ * 1. set Window Flag : WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
|
|
|
|
|
+ * 2. removeFakeStatusBarViewIfExist
|
|
|
|
|
+ * 3. addFakeStatusBarView
|
|
|
|
|
+ * 4. addMarginTopToContentChild
|
|
|
|
|
+ * 5. cancel ContentChild's fitsSystemWindow
|
|
|
|
|
+ */
|
|
|
|
|
+ static void setStatusBarColor(Activity activity, int statusColor) {
|
|
|
|
|
+ Window window = activity.getWindow();
|
|
|
|
|
+ window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
|
|
|
|
|
+
|
|
|
|
|
+ ViewGroup mContentView = (ViewGroup) window.findViewById(Window.ID_ANDROID_CONTENT);
|
|
|
|
|
+ View mContentChild = mContentView.getChildAt(0);
|
|
|
|
|
+ int statusBarHeight = getStatusBarHeight(activity);
|
|
|
|
|
+
|
|
|
|
|
+ removeFakeStatusBarViewIfExist(activity);
|
|
|
|
|
+ addFakeStatusBarView(activity, statusColor, statusBarHeight);
|
|
|
|
|
+ addMarginTopToContentChild(mContentChild, statusBarHeight);
|
|
|
|
|
+
|
|
|
|
|
+ if (mContentChild != null) {
|
|
|
|
|
+ ViewCompat.setFitsSystemWindows(mContentChild, false);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * translucentStatusBar
|
|
|
|
|
+ *
|
|
|
|
|
+ * 1. set Window Flag : WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
|
|
|
|
|
+ * 2. removeFakeStatusBarViewIfExist
|
|
|
|
|
+ * 3. removeMarginTopOfContentChild
|
|
|
|
|
+ * 4. cancel ContentChild's fitsSystemWindow
|
|
|
|
|
+ */
|
|
|
|
|
+ static void translucentStatusBar(Activity activity) {
|
|
|
|
|
+ Window window = activity.getWindow();
|
|
|
|
|
+ window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
|
|
|
|
|
+
|
|
|
|
|
+ ViewGroup mContentView = (ViewGroup) activity.findViewById(Window.ID_ANDROID_CONTENT);
|
|
|
|
|
+ View mContentChild = mContentView.getChildAt(0);
|
|
|
|
|
+
|
|
|
|
|
+ removeFakeStatusBarViewIfExist(activity);
|
|
|
|
|
+ removeMarginTopOfContentChild(mContentChild, getStatusBarHeight(activity));
|
|
|
|
|
+ if (mContentChild != null) {
|
|
|
|
|
+ ViewCompat.setFitsSystemWindows(mContentChild, false);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * compat for CollapsingToolbarLayout
|
|
|
|
|
+ *
|
|
|
|
|
+ * 1. set Window Flag : WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
|
|
|
|
|
+ * 2. set FitsSystemWindows for views.
|
|
|
|
|
+ * 3. add Toolbar's height, let it layout from top, then add paddingTop to layout normal.
|
|
|
|
|
+ * 4. removeFakeStatusBarViewIfExist
|
|
|
|
|
+ * 5. removeMarginTopOfContentChild
|
|
|
|
|
+ * 6. add OnOffsetChangedListener to change statusBarView's alpha
|
|
|
|
|
+ */
|
|
|
|
|
+ static void setStatusBarColorForCollapsingToolbar(Activity activity, final AppBarLayout appBarLayout, final CollapsingToolbarLayout collapsingToolbarLayout,
|
|
|
|
|
+ Toolbar toolbar, int statusColor) {
|
|
|
|
|
+ Window window = activity.getWindow();
|
|
|
|
|
+ window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
|
|
|
|
|
+ ViewGroup mContentView = (ViewGroup) window.findViewById(Window.ID_ANDROID_CONTENT);
|
|
|
|
|
+
|
|
|
|
|
+ View mContentChild = mContentView.getChildAt(0);
|
|
|
|
|
+ mContentChild.setFitsSystemWindows(false);
|
|
|
|
|
+ ((View) appBarLayout.getParent()).setFitsSystemWindows(false);
|
|
|
|
|
+ appBarLayout.setFitsSystemWindows(false);
|
|
|
|
|
+ collapsingToolbarLayout.setFitsSystemWindows(false);
|
|
|
|
|
+ collapsingToolbarLayout.getChildAt(0).setFitsSystemWindows(false);
|
|
|
|
|
+
|
|
|
|
|
+ toolbar.setFitsSystemWindows(false);
|
|
|
|
|
+ if (toolbar.getTag() == null) {
|
|
|
|
|
+ CollapsingToolbarLayout.LayoutParams lp = (CollapsingToolbarLayout.LayoutParams) toolbar.getLayoutParams();
|
|
|
|
|
+ int statusBarHeight = getStatusBarHeight(activity);
|
|
|
|
|
+ lp.height += statusBarHeight;
|
|
|
|
|
+ toolbar.setLayoutParams(lp);
|
|
|
|
|
+ toolbar.setPadding(toolbar.getPaddingLeft(), toolbar.getPaddingTop() + statusBarHeight, toolbar.getPaddingRight(), toolbar.getPaddingBottom());
|
|
|
|
|
+ toolbar.setTag(true);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ int statusBarHeight = getStatusBarHeight(activity);
|
|
|
|
|
+ removeFakeStatusBarViewIfExist(activity);
|
|
|
|
|
+ removeMarginTopOfContentChild(mContentChild, statusBarHeight);
|
|
|
|
|
+ final View statusView = addFakeStatusBarView(activity, statusColor, statusBarHeight);
|
|
|
|
|
+
|
|
|
|
|
+ CoordinatorLayout.Behavior behavior = ((CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams()).getBehavior();
|
|
|
|
|
+ if (behavior != null && behavior instanceof AppBarLayout.Behavior) {
|
|
|
|
|
+ int verticalOffset = ((AppBarLayout.Behavior) behavior).getTopAndBottomOffset();
|
|
|
|
|
+ if (Math.abs(verticalOffset) > appBarLayout.getHeight() - collapsingToolbarLayout.getScrimVisibleHeightTrigger()) {
|
|
|
|
|
+ statusView.setAlpha(1f);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ statusView.setAlpha(0f);
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ statusView.setAlpha(0f);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
|
|
|
|
|
+ if (Math.abs(verticalOffset) > appBarLayout.getHeight() - collapsingToolbarLayout.getScrimVisibleHeightTrigger()) {
|
|
|
|
|
+ if (statusView.getAlpha() == 0) {
|
|
|
|
|
+ statusView.animate().cancel();
|
|
|
|
|
+ statusView.animate().alpha(1f).setDuration(collapsingToolbarLayout.getScrimAnimationDuration()).start();
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ if (statusView.getAlpha() == 1) {
|
|
|
|
|
+ statusView.animate().cancel();
|
|
|
|
|
+ statusView.animate().alpha(0f).setDuration(collapsingToolbarLayout.getScrimAnimationDuration()).start();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+}
|