300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > Android自定义修改状态栏(字体颜色均可修改)

Android自定义修改状态栏(字体颜色均可修改)

时间:2019-02-07 07:36:28

相关推荐

Android自定义修改状态栏(字体颜色均可修改)

状态栏

在一些安卓app中,我们会发现app界面上方状态栏的字体和颜色与手机待机时不一样,难道系统会根据背景去主动变色??答案当然是否定的,系统绝对不会根据背景去主动变色。而是需要我们去手动改变系统状态栏的背景和字体颜色。之前接到一个需求就是要求系统状态栏改变,然后就在网上找了一些所谓的可以改变的文章,试了之后发现没有什么卵用。最后在多篇文章中找到了一些可用的类,然后自己组合了一下,发现可以达到需要的结果。特此记录,方便大家指导和后续使用。

首先看看对比效果:

右图中的就是改过的样式,看起来和谐了一点是吧,,,,

activity调用很简单。共两行:

StatusBarCompat.translucentStatusBar(activity, false);StatusBarUtil.setImmersiveStatusBar(activity, true);

StatusBarCompat类。先判断版本号,然后根据版本号调用不同的版本去处理状态栏。全码如下:

package .systembar;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() {@Overridepublic 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();}}}});}}

注:找不到的类可在源码中复制,这里就不写了,有点多。

StatusBarUtil类。同样是根据版本号去使用不同的方式去处理。全码如下:

package .systembar;import android.annotation.TargetApi;import android.app.Activity;import android.graphics.Color;import android.os.Build;import android.support.annotation.IntDef;import android.view.View;import android.view.Window;import android.view.WindowManager;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.reflect.Field;import java.lang.reflect.Method;public class StatusBarUtil {public final static int TYPE_MIUI = 0;public final static int TYPE_FLYME = 1;public final static int TYPE_M = 3;//6.0@IntDef({TYPE_MIUI,TYPE_FLYME,TYPE_M})@Retention(RetentionPolicy.SOURCE)@interface ViewType {}/*** 修改状态栏颜色,支持4.4以上版本* @param colorId 颜色*/public static void setStatusBarColor(Activity activity, int colorId) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {Window window = activity.getWindow();window.setStatusBarColor(colorId);} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {//使用SystemBarTintManager,需要先将状态栏设置为透明setTranslucentStatus(activity);SystemBarTintManager systemBarTintManager = new SystemBarTintManager(activity);systemBarTintManager.setStatusBarTintEnabled(true);//显示状态栏systemBarTintManager.setStatusBarTintColor(colorId);//设置状态栏颜色}}/*** 设置状态栏透明*/@TargetApi(19)public static void setTranslucentStatus(Activity activity) {// 5.0以上系统状态栏透明if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {Window window = activity.getWindow();//清除透明状态栏window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN| View.SYSTEM_UI_FLAG_LAYOUT_STABLE);//设置状态栏颜色必须添加window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);window.setStatusBarColor(Color.TRANSPARENT);//设置透明} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { //19activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);}}/*** 设置沉浸式状态栏** @param fontIconDark 状态栏字体和图标颜色是否为深色*/public static void setImmersiveStatusBar(Activity activity,boolean fontIconDark) {setStatusBarColor(activity, Color.WHITE);if (fontIconDark) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {setStatusBarFontIconDark(activity,TYPE_M);} else if (OSUtils.isMiui()) {setStatusBarFontIconDark(activity,TYPE_MIUI);} else if (OSUtils.isFlyme()) {setStatusBarFontIconDark(activity,TYPE_FLYME);} else {//其他情况下我们将状态栏设置为灰色,就不会看不见字体setStatusBarColor(activity,Color.LTGRAY);//灰色}}}/*** 设置文字颜色*/public static void setStatusBarFontIconDark(Activity activity,@ViewType int type) {switch (type) {case TYPE_MIUI:setMiuiUI(activity,true);break;case TYPE_M:setCommonUI(activity);break;case TYPE_FLYME:setFlymeUI(activity,true);break;}}//设置6.0的字体public static void setCommonUI(Activity activity) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN| View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);}}//设置Flyme的字体public static void setFlymeUI(Activity activity,boolean dark) {try {Window window = activity.getWindow();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);} catch (Exception e) {e.printStackTrace();}}//设置MIUI字体public static void setMiuiUI(Activity activity,boolean dark) {try {Window window = activity.getWindow();Class clazz = activity.getWindow().getClass();Class layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams");Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE");int 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);}} catch (Exception e) {e.printStackTrace();}}}

切记字体设置只有白色和黑色两种,如果要自行修改,去类中修改即可

到这为止,所有的功能都已经添加ok了。

附上demo源码

/download/qq_35840038/11013569

q:486789970

email:mr.cai_cai@

如果有什么问题,欢迎大家指导。并相互联系,希望能够通过文章互相学习。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。