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

来源:互联网 发布:数据库的设计原则答案 编辑:程序博客网 时间:2024/05/17 07:56

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中动态改变和如何把布局延伸到状态栏中。

原创粉丝点击