ToolBar的封装、动态改变状态栏颜色

1.前言

上一篇文章介绍了ToolBar的使用方法,在日常开发中ToolBar会在很多的Activity中同时使用,所以我们有必要把ToolBar进行封装,方便调用。

2.ToolBar的封装

基本思路是写一个单独的ToolBar的文件,再写一个基类Activity重写它的setContentView()方法,在这个方法里添加ToolBar。具体代码如下:

package bcjm.myapplication;

import android.support.annotation.LayoutRes;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;

/**
 * Created by lx on 2017/11/24.
 */

public abstract class BaseActivity extends AppCompatActivity {
    protected Toolbar toolbar;
    private boolean showToolBar = true;
    protected TitleBarView titleBarView;


    @Override
    public void setContentView(@LayoutRes int layoutResID) {

        //使用自定义的TitleBarView,不推荐
        if (isShowTitleBar()) {
            titleBarView = new TitleBarView(this);
            titleBarView.setBtnLeftOnclickListener(new View.OnClickListener() {

                @Override
                public void onClick(View v) {
                    finish();
                }
            });
            LinearLayout linearLayout = new LinearLayout(this);
            linearLayout.setId(R.id.ll_container_id);
            linearLayout.setOrientation(LinearLayout.VERTICAL);
            linearLayout.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
            linearLayout.addView(titleBarView);
            View view = getLayoutInflater().inflate(layoutResID, null);
            linearLayout.addView(view, LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
            super.setContentView(linearLayout);
            //强烈推荐使用ToolBar
        } else if (isShowToolBar()) {
            toolbar = (Toolbar) getLayoutInflater().inflate(R.layout.toolbar, null);
            toolbar.setTitle("");
            setSupportActionBar(toolbar);
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
            LinearLayout linearLayout = new LinearLayout(this);
            linearLayout.setId(R.id.ll_container_id);
            linearLayout.setOrientation(LinearLayout.VERTICAL);
          linearLayout.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
            linearLayout.addView(toolbar, LinearLayout.LayoutParams.MATCH_PARENT, DensityUtil.dipToPixels(this, 50));
            View view = getLayoutInflater().inflate(layoutResID, null);
            linearLayout.addView(view, LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
            super.setContentView(linearLayout);
        } else {
            super.setContentView(layoutResID);
        }

        StatusBarUtils.setColor(this, R.color.colorPrimaryDark);
    }


    /***
     * 如果需要设置TitleBarView 重写这个方法 setshowToolBar(false);
     * @return
     */
    protected boolean isShowTitleBar() {
        return false;
    }

    protected void setShowToolBar(boolean isShow) {
        showToolBar = isShow;
    }

    protected boolean isShowToolBar() {
        return showToolBar;
    }

    /**
     * 设置返回按钮是否可见
     *
     * @param visible
     */
    protected void setBackVisible(boolean visible) {
        getSupportActionBar().setDisplayHomeAsUpEnabled(visible);
    }

    protected abstract void initTitleView();

    protected abstract void initView();


}

这里提供了2种方式显示标题栏,一种是使用自定义控件TitleBarView来显示标题栏,另一种使用ToolBar来显示标题栏。这里强烈推荐ToolBar,如果ToolBar不满足你的需求,可以使用TitleBarView来自定义标题栏。使用TitleBarView是需要setShowToolBar(false),并重写isShowTitleBar()方法。

3.改变状态栏颜色

改变状态栏颜色包括改变状态栏背景颜色和状态栏字体颜色

3.1改变状态栏背景颜色

在应用主题style中可以通过设置:

 <!-- 状态栏颜色 -->
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>

但这个只有在android 5.0版本及以上才生效。在android 5.0以下是没有效果的默认是黑色背景白色字体。
我们也可以通过代码来动态设置状态栏背景颜色,并可以适配到android 4.4及以上。代码如下:

import android.app.Activity;
import android.os.Build;
import android.support.annotation.ColorRes;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;

/**
 * Created by lx on 2017/11/28.
 */

public class StatusBarUtils {


    /**
     * 设置状态栏颜色
     * @param activity
     * @param color
     */
    public static void setColor(Activity activity,@ColorRes  int color){
        //如果版本大于等于5.0,直接用系统的api
        if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.LOLLIPOP){
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            activity.getWindow().setStatusBarColor(activity.getResources().getColor(color));

            //如果版本大于等于4.4小于5.0,先把状态栏设置为透明的,再加一个View上去;小于android4.4系统
            //不支持设置透明状态栏,所以无法更改
        }else if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.KITKAT){
           //设置透明           activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            //获取屏幕的根布局
            ViewGroup viewGroup = (ViewGroup) activity.getWindow().getDecorView();

            int count = viewGroup.getChildCount();
            boolean isAdd = false;
            int j = -1;
            for (int i = 0; i < count; i++) {
                View view = viewGroup.getChildAt(i);
                if (view instanceof StatusBarView) {
                    j = i;
                    isAdd = true;
                    break;
                }
            }
            if (j != -1 && isAdd && viewGroup.getChildAt(j) instanceof StatusBarView) {
                StatusBarView statusview = (StatusBarView) viewGroup.getChildAt(j);
                statusview.setBackgroundColor(activity.getResources().getColor(color));
            } else {
                StatusBarView statusBarView = new StatusBarView(activity);
                ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                        getStatusBarHeight(activity));
                statusBarView.setLayoutParams(layoutParams);
                statusBarView.setBackgroundColor(activity.getResources().getColor(color));
                viewGroup.addView(statusBarView);
            }
            setRootView(activity, true);
        }
    }

    /**
     * 设置根布局参数
     */
    private static void setRootView(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);
            }
        }
    }

    public static int  getStatusBarHeight(Activity activity){
        int resId=activity.getResources().getIdentifier("status_bar_height","dimen","android");
        int height=activity.getResources().getDimensionPixelSize(resId);
        return height;
    }
}

在android 4.4利用WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS透明状态栏的属性,自己添加一个和状态栏一样大小的View来设置状态栏背景颜色。目前对于android4.4以下的系统是无法设置状态背景颜色的。

3.2设置状态栏字体颜色

目前就小米和魅族提供相应的方法来修改状态栏颜色还有android 6.0及以上系统支持修改状态栏颜色。我把他们简单封装了一些:部分代码如下:

   /**
     *设置状态栏黑色字体图标,
     * 适配4.4以上版本MIUIV、Flyme和6.0以上版本其他Android
     * @param activity
     * @return 1:MIUUI 2:Flyme 3:android6.0
     */
    public static int StatusBarLightMode(Activity activity){
        int result=0;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
          //如果是小米系统
            if(SystemUtil.getSystem().equals(SystemUtil.SYS_MIUI)
                    &&MIUISetStatusBarLightMode(activity,true)){
                result=1;
                //如果是魅族系统
            }else if(SystemUtil.getSystem().equals(SystemUtil.SYS_FLYME)) {
                StatusbarColorUtils.setStatusBarDarkIcon(activity, true);
                result = 2;
                //android 6.0系统
            } else if (Build.VERSION.SDK_INT >=23) {
                activity.getWindow().setStatusBarColor(Color.WHITE);
                activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
               // activity.getWindow().getDecorView().setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN|0x00002000);
                result=3;
            }
        }
        return result;
    }



  /**
     * 设置状态栏字体图标为深色,需要MIUIV6以上
     * @param activity a
     * @param dark 是否把状态栏字体及图标颜色设置为深色
     * @return  boolean 成功执行返回true
     *
     */
    public static boolean MIUISetStatusBarLightMode(Activity activity, boolean dark) {
        boolean result = false;
        if (activity != null) {
            Class clazz = activity.getWindow().getClass();
            try {
                int darkModeFlag = 0;
                Class layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams");
                Field  field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE");
                darkModeFlag = field.getInt(layoutParams);
                Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class);
                if(dark){
                    extraFlagField.invoke(activity.getWindow(),darkModeFlag,darkModeFlag);//状态栏透明且黑色字体
                }else{
                    extraFlagField.invoke(activity.getWindow(), 0, darkModeFlag);//清除黑色字体
                }
                result=true;
            }catch (Exception e){

            }
        }
        return result;
    }

判断手机系统帮助类

public class SystemUtil {
    public static final String SYS_EMUI = "sys_emui";
    public static final String SYS_MIUI = "sys_miui";
    public static final String SYS_FLYME = "sys_flyme";
    private static final String KEY_MIUI_VERSION_CODE = "ro.miui.ui.version.code";
    private static final String KEY_MIUI_VERSION_NAME = "ro.miui.ui.version.name";
    private static final String KEY_MIUI_INTERNAL_STORAGE = "ro.miui.internal.storage";
    private static final String KEY_EMUI_API_LEVEL = "ro.build.hw_emui_api_level";
    private static final String KEY_EMUI_VERSION = "ro.build.version.emui";
    private static final String KEY_EMUI_CONFIG_HW_SYS_VERSION = "ro.confg.hw_systemversion";

    public static String getSystem(){
        String SYS="";
        try {
            Properties prop= new Properties();
            prop.load(new FileInputStream(new File(Environment.getRootDirectory(), "build.prop")));
            if(prop.getProperty(KEY_MIUI_VERSION_CODE, null) != null
                    || prop.getProperty(KEY_MIUI_VERSION_NAME, null) != null
                    || prop.getProperty(KEY_MIUI_INTERNAL_STORAGE, null) != null){
                SYS = SYS_MIUI;//小米
            }else if(prop.getProperty(KEY_EMUI_API_LEVEL, null) != null
                    ||prop.getProperty(KEY_EMUI_VERSION, null) != null
                    ||prop.getProperty(KEY_EMUI_CONFIG_HW_SYS_VERSION, null) != null){
                SYS = SYS_EMUI;//华为
            }else if(getMeizuFlymeOSFlag().toLowerCase().contains("flyme")){
                SYS = SYS_FLYME;//魅族
            };
        } catch (IOException e){
            e.printStackTrace();
            return SYS;
        }
        return SYS;
    }

    public static String getMeizuFlymeOSFlag() {
        return getSystemProperty("ro.build.display.id", "");
    }

    private static String getSystemProperty(String key, String defaultValue) {
        try {
            Class<?> clz = Class.forName("android.os.SystemProperties");
            Method get = clz.getMethod("get", String.class, String.class);
            return (String)get.invoke(clz, key, defaultValue);
        } catch (Exception e) {
        }
        return defaultValue;
    }
}

其中 StatusbarColorUtils类可以在魅族开发者官网可以下载

4.0总结

本篇文章主要介绍了ToolBar的封装,改变状态栏颜色,其中改变状态栏字体颜色限制较多。可能有的机型会不适配。下一章我们继续介绍在状态栏,状态栏在Fragment中动态改变和如何把布局延伸到状态栏中。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值