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中动态改变和如何把布局延伸到状态栏中。
- ToolBar的封装、动态改变状态栏颜色
- 改变状态栏的颜色
- 改变状态栏的颜色
- 改变状态栏的颜色
- 改变状态栏文字的颜色
- 如何改变状态栏的颜色
- android 状态栏颜色的改变
- [Android]改变状态栏的颜色
- 改变Android状态栏的颜色
- 改变状态栏statusbar的颜色
- Android5.0沉浸式状态栏,以及动态改变状态栏颜色
- 使用ToolBar改变旋转图表的颜色
- ios7状态栏字体颜色的改变
- iOS改变状态栏的字体颜色
- iOS 改变状态栏的颜色(样式)
- Android 改变顶部状态栏的颜色
- 改变手机状态栏(statusBar)的颜色
- Android开发改变状态栏的颜色
- OOALV单个container放置多个ALV grid
- 小东吖 之 java的基础知识以及break 和 continue 关键字的使用
- 关于SSH的经典知识
- JAVA 与 MyCat(2) 单例模式
- STL(五)list 双向链表
- ToolBar的封装、动态改变状态栏颜色
- 20171130_tensorflow_tf.Variable
- CentOS7 下安装docker和docker-compose
- 面向对象(上)
- 获取python未知异常信息的方法
- 基于最小均方差(维纳)滤波的图像去模糊
- java.lang.NoSuchMethodError: redis.clients.jedis.JedisShardInfo.setTimeout(I)V
- 九九乘法表
- java一个循环打印三角形