今天为大家介绍 5 个处理状态栏的函数,这 5 个函数互不依赖,可以自由以任意次序组合以达成自己的需求。支持到 Android 4.4 。
如图所示:
沉浸式
public static void setStatusBarTranslucent(Window window, boolean translucent) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { View decorView = window.getDecorView(); if (translucent) { decorView.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() { @TargetApi(Build.VERSION_CODES.LOLLIPOP) @Override public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) { WindowInsets defaultInsets = v.onApplyWindowInsets(insets); return defaultInsets.replaceSystemWindowInsets( defaultInsets.getSystemWindowInsetLeft(), 0, defaultInsets.getSystemWindowInsetRight(), defaultInsets.getSystemWindowInsetBottom()); } }); } else { decorView.setOnApplyWindowInsetsListener(null); } ViewCompat.requestApplyInsets(decorView); } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { if (translucent) { window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); } else { window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); } ViewCompat.requestApplyInsets(window.getDecorView()); }}复制代码
状态栏着色
public static void setStatusBarColor(final Window window, int color, boolean animated) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); if (animated) { int curColor = window.getStatusBarColor(); ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), curColor, color); colorAnimation.addUpdateListener( new ValueAnimator.AnimatorUpdateListener() { @TargetApi(21) @Override public void onAnimationUpdate(ValueAnimator animator) { window.setStatusBarColor((Integer) animator.getAnimatedValue()); } }); colorAnimation.setDuration(200).setStartDelay(0); colorAnimation.start(); } else { window.setStatusBarColor(color); } } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { ViewGroup decorViewGroup = (ViewGroup) window.getDecorView(); View statusBarView = decorViewGroup.findViewWithTag("custom_status_bar_tag"); if (statusBarView == null) { statusBarView = new View(window.getContext()); statusBarView.setTag("custom_status_bar_tag"); FrameLayout.LayoutParams params = new FrameLayout.LayoutParams( FrameLayout.LayoutParams.MATCH_PARENT, getStatusBarHeight(window.getContext())); params.gravity = Gravity.TOP; statusBarView.setLayoutParams(params); decorViewGroup.addView(statusBarView); } if (animated) { Drawable drawable = statusBarView.getBackground(); int curColor = Integer.MAX_VALUE; if (drawable != null && drawable instanceof ColorDrawable) { ColorDrawable colorDrawable = (ColorDrawable) drawable; curColor = colorDrawable.getColor(); } if (curColor != Integer.MAX_VALUE) { final View barView = statusBarView; ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), curColor, color); colorAnimation.addUpdateListener( new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animator) { barView.setBackground(new ColorDrawable((Integer) animator.getAnimatedValue())); } }); colorAnimation.setDuration(200).setStartDelay(0); colorAnimation.start(); } else { statusBarView.setBackground(new ColorDrawable(color)); } } else { statusBarView.setBackground(new ColorDrawable(color)); } }}复制代码
黑色状态栏
public static void setStatusBarStyle(Window window, boolean dark) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { View decorView = window.getDecorView(); decorView.setSystemUiVisibility( dark ? View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR : 0); }}复制代码
隐藏状态栏
public static void setStatusBarHidden(Window window, boolean hidden) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { if (hidden) { window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); window.clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN); } else { window.addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN); window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); } } if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) { ViewGroup decorViewGroup = (ViewGroup) window.getDecorView(); final View statusBarView = decorViewGroup.findViewWithTag("custom_status_bar_tag"); if (statusBarView != null) { boolean hiding = statusBarView.isClickable(); if (hiding == hidden) { return; } if (hidden) { statusBarView.setClickable(true); ObjectAnimator animator = ObjectAnimator.ofFloat(statusBarView, "y", -getStatusBarHeight(window.getContext())); animator.setDuration(200); animator.setStartDelay(200); animator.start(); } else { statusBarView.setClickable(false); ObjectAnimator animator = ObjectAnimator.ofFloat(statusBarView, "y", 0); animator.setDuration(200); animator.start(); } } }}复制代码
调整 Toolbar 位置
public static void appendStatusBarPadding(View view, int viewHeight) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { if (view != null) { int statusBarHeight = getStatusBarHeight(view.getContext()); view.setPadding(view.getPaddingLeft(), statusBarHeight, view.getPaddingRight(), view.getPaddingBottom()); if (viewHeight > 0) { view.getLayoutParams().height = statusBarHeight + viewHeight; } else { view.getLayoutParams().height = viewHeight; } } }}public static void removeStatusBarPadding(View view, int viewHeight) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { if (view != null) { view.setPadding(view.getPaddingLeft(), 0, view.getPaddingRight(), view.getPaddingBottom()); view.getLayoutParams().height = viewHeight; } }}public static int getStatusBarHeight(Context context) { int statusBarHeight = -1; //获取status_bar_height资源的ID int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android"); if (resourceId > 0) { //根据资源ID获取响应的尺寸值 statusBarHeight = context.getResources().getDimensionPixelSize(resourceId); } return statusBarHeight;}复制代码
在 Fragment 中使用
有时,一个 Activity 中有好几个 fragment, 每个 fragment 的状态栏样式可能都不一样,如何优雅地跟随 fragment 切换状态栏的样式呢?就像下图所示的那样?
要达成这样的效果需要作一定的封装,这里有一个封装好的方案,只需要有选择地重写下面几个方法,简单返回想要的效果即可。
protected BarStyle preferredStatusBarStyle();protected boolean preferredStatusBarHidden();protected int preferredStatusBarColor();protected boolean preferredStatusBarColorAnimated();复制代码