Android 沉浸式状态栏 渐变颜色的实现

最近在开发中遇到一种个性化的需求,类似于QQ顶部的渐变状态栏的实现,如下图

首先我们要了解在Android5.0以后,系统API提供直接设置StatusBar来改变状态栏的颜色,然而在4.4上StatusBar变色的基本原理就是将StatusBar本身设置为透明,然后在StatusBar的位置添加一个相同大小的View并上色。没办法,我们要做的渐变颜色状态栏就是要兼容上下版本的差异

更多关于沉浸式状态栏的了解可参考洪洋大神的文章

Android 沉浸式状态栏攻略 让你的状态栏变色吧

纯色兼容状态栏

 /*** 设置状态栏颜色** @param activity       需要设置的activity* @param color          状态栏颜色值* @param statusBarAlpha 状态栏透明度*/public static void setColor(Activity activity, @ColorInt int color, @IntRange(from = 0, to = 255) int statusBarAlpha) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {//5.0以上版本//设置FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS属性才能调用setStatusBarColor方法来设置状态栏颜色activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);//设置FLAG_TRANSLUCENT_STATUS透明状态栏activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);//根据输入的颜色和透明度显示activity.getWindow().setStatusBarColor(calculateStatusColor(color, statusBarAlpha));} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {//低版本//添加透明状态栏activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);//获取顶级视图ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();//获取顶部的StatusBarView,自定义StatusBarView的Id(在resources中创建Id)View fakeStatusBarView = decorView.findViewById(R.id.statusbarutil_fake_status_bar_view);if (fakeStatusBarView != null) {if (fakeStatusBarView.getVisibility() == View.GONE) {fakeStatusBarView.setVisibility(View.VISIBLE);}//设置顶层颜色fakeStatusBarView.setBackgroundColor(calculateStatusColor(color, statusBarAlpha));} else {//上述不符合,则创建一个View添加到顶级视图中decorView.addView(createStatusBarView(activity, color, statusBarAlpha));}setRootView(activity);}}

calculateStatusColor(计算状态栏颜色)

 /*** 计算状态栏颜色** @param color color值* @param alpha alpha值* @return 最终的状态栏颜色*/private static int calculateStatusColor(@ColorInt int color, int alpha) {if (alpha == 0) {return color;}float a = 1 - alpha / 255f;int red = color >> 16 & 0xff;int green = color >> 8 & 0xff;int blue = color & 0xff;red = (int) (red * a + 0.5);green = (int) (green * a + 0.5);blue = (int) (blue * a + 0.5);return 0xff << 24 | red << 16 | green << 8 | blue;}

getStatusBarHeight(获取状态栏高度)

 /*** 获取状态栏高度** @param context context* @return 状态栏高度*/public static int getStatusBarHeight(Context context) {// 获得状态栏高度int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");return context.getResources().getDimensionPixelSize(resourceId);}

自定义View状态栏

 /*** 自定义View状态栏** @param activity 需要设置的activity* @param color    状态栏颜色值* @param alpha    透明值* @return 状态栏矩形条*/private static View createStatusBarView(Activity activity, @ColorInt int color, int alpha) {// 绘制一个和状态栏一样高的矩形View statusBarView = new View(activity);LinearLayout.LayoutParams params =new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(activity));statusBarView.setLayoutParams(params);statusBarView.setBackgroundColor(calculateStatusColor(color, alpha));//自定义的StatusBarView的IdstatusBarView.setId(FAKE_STATUS_BAR_VIEW_ID);return statusBarView;}

最后重新规划布局

setRootView(重新设置根布局)

  /*** 设置根布局参数*/private static void setRootView(Activity activity) {//ViewGroup容器存放UI组件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);}}}

由此纯色状态栏的基本配置就可以了,只需要创建Utils工具类在Activity中调用即可,

 //设置纯色状态栏StatusBarUtil.setColor(this, AppUtils.getColor(R.color.colorPrimary));

渐变色兼容状态栏

关于渐变颜色的状态栏,实现方法有很多种,比如(反射拿到StatusBar并设置setBackgroundResource将shape渐变颜色添加进来即可,创建View填充状态栏),这里我们介绍的是第二种方法,创建View填充状态栏(有没有方法跟上面的方法很类似)

代码如下

  /*** 为界面设置自定义透明View** @param activity       需要设置的activity* @param statusBarAlpha 状态栏透明度* @param needOffsetView 需要向下偏移的 Viewpublic static void setTranslucentForWindow(Activity activity, @IntRange(from = 0, to = 255) int statusBarAlpha,View needOffsetView) {if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {//5.0以上版本setTransparentForWindow(activity);addTranslucentView(activity, statusBarAlpha);if (needOffsetView != null) {Object haveSetOffset = needOffsetView.getTag(TAG_KEY_HAVE_SET_OFFSET);if (haveSetOffset != null && (Boolean) haveSetOffset) {return;}ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) needOffsetView.getLayoutParams();layoutParams.setMargins(layoutParams.leftMargin, layoutParams.topMargin + getStatusBarHeight(activity),layoutParams.rightMargin, layoutParams.bottomMargin);needOffsetView.setTag(TAG_KEY_HAVE_SET_OFFSET, true);}} else {//低版本//添加透明状态栏activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);//获取顶级视图ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();//获取顶部的StatusBarView,自定义idView fakeStatusBarView = decorView.findViewById(FAKE_STATUS_BAR_VIEW_ID);if (fakeStatusBarView != null) {if (fakeStatusBarView.getVisibility() == View.GONE) {fakeStatusBarView.setVisibility(View.VISIBLE);}//设置顶层颜色fakeStatusBarView.setBackgroundResource(R.drawable.shape_gradient);} else {//上述不符合,则创建一个View添加到顶级视图中View statusBarView = new View(activity);LinearLayout.LayoutParams params =new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(activity));statusBarView.setLayoutParams(params);fakeStatusBarView.setBackgroundResource(R.drawable.shape_gradient);statusBarView.setId(FAKE_STATUS_BAR_VIEW_ID);decorView.addView(statusBarView);}setRootView(activity);}}

getStatusBarHeight(获取状态栏高度)

 /*** 获取状态栏高度** @param context context* @return 状态栏高度*/public static int getStatusBarHeight(Context context) {// 获得状态栏高度int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");return context.getResources().getDimensionPixelSize(resourceId);}

setTransparentForWindow(设置状态栏透明)

/*** 设置透明*/public static void setTransparentForWindow(Activity activity) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {activity.getWindow().setStatusBarColor(Color.TRANSPARENT);activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);}}

addTranslucentView(添加半透明矩形)

/*** 添加半透明矩形条** @param activity       需要设置的 activity* @param statusBarAlpha 透明值*/private static void addTranslucentView(Activity activity, @IntRange(from = 0, to = 255) int statusBarAlpha) {ViewGroup contentView = (ViewGroup) activity.findViewById(android.R.id.content);//系统IdView fakeTranslucentView = contentView.findViewById(FAKE_TRANSLUCENT_VIEW_ID);if (fakeTranslucentView != null) {if (fakeTranslucentView.getVisibility() == View.GONE) {fakeTranslucentView.setVisibility(View.VISIBLE);}fakeTranslucentView.setBackgroundColor(Color.argb(statusBarAlpha, 0, 0, 0));} else {contentView.addView(createTranslucentStatusBarView(activity, statusBarAlpha));}}

由此渐变颜色的状态栏设置,只需要将toolbar作为View传入,调用如下

//设置渐变颜色状态栏(调用方法)
StatusBarUtil.setTransparentForWindow(this, mToolbar);//布局如下
<?xml version="1.0" encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="wrap_content"><android.support.design.widget.AppBarLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:background="@drawable/shape_gradient"android:theme="@style/AppTheme.AppBarOverlay"app:elevation="@dimen/dp0"><android.support.v7.widget.Toolbarandroid:id="@+id/toolbar"android:layout_width="match_parent"android:layout_height="?attr/actionBarSize"app:popupTheme="@style/ToolbarPopupTheme"app:title="@string/main_toolbar_title_top"app:titleTextColor="@color/colorPrimary"></android.support.v7.widget.Toolbar></android.support.design.widget.AppBarLayout>
</LinearLayout>

Demo Link

至此,渐变色状态栏的配置已经介绍完全了,细想下纯色状态栏中的实现也有类似的操作,再结合一下就实现了兼容上下版本的效果

Android 沉浸式状态栏 渐变颜色的实现相关推荐

  1. android布局黑色字体颜色,Android 沉浸式状态栏-字体颜色与背景颜色修改实现与兼容...

    沉浸式状态栏究其根本就是将布局内容延伸到状态栏中,让状态栏覆盖在布局上或者隐藏. 实现 首先,要修改状态栏android版本至少要在4.4以上,并且在4.4是不能让状态栏透明的,只能达到一种半透明的阴 ...

  2. Android 沉浸式状态栏-字体颜色与背景颜色修改实现与兼容

    沉浸式状态栏究其根本就是将布局内容延伸到状态栏中,让状态栏覆盖在布局上或者隐藏. 实现 首先,要修改状态栏android版本至少要在4.4以上,并且在4.4是不能让状态栏透明的,只能达到一种半透明的阴 ...

  3. android 沉浸式状态栏字体颜色,改变Android状态栏字体颜色和实现沉浸式状态栏

    目前已知的改变Android状态栏字体颜色的方法只有3种情况下可以实现,分别是手机是MIUI系统.魅族手机以及Android6.0.改变颜色方法分别如下: * 改变小米的状态栏字体颜色为黑色, 要求M ...

  4. Android底部菜单栏、Android沉浸式状态栏(顶部状态栏修改颜色)、自定义标题栏

    0.简介: 没有使用TabHost切换,而是变成FragmentActivity替换Fragment:沉浸式引用的git上面的jar包. 先看图片 1.底部导航栏 核心代码 <span styl ...

  5. android沉浸式 字体,Android沉浸式状态栏背景色以及字体颜色的修改

    在activity中设置透明状态栏 的思路: 1.让activity的布局全屏 此时布局会和状态栏重叠 2.让布局最上方预留出和状态栏高度一样的高度,将状态栏的背景色设置为透明 效果如下: 一般是在s ...

  6. 高大上的Android沉浸式状态栏?

    背景 之前做过Android沉浸式状态栏的相关需求,但是一直忙于工作,没时间系统的整理下沉浸式相关的知识,所以今天抽出时间,写一篇 Android沉浸式状态栏的文章. 何为沉浸式 沉浸式就是要给用户提 ...

  7. Android沉浸式状态栏,看完这篇就够了!

    背景 之前做过Android沉浸式状态栏的相关需求,但是一直忙于工作,没时间系统的整理下沉浸式相关的知识,所以今天抽出时间,写一篇 Android沉浸式状态栏的文章. 何为沉浸式 沉浸式就是要给用户提 ...

  8. Android沉浸式状态栏(透明系统状态栏)

    Android沉浸式状态栏(透明系统状态栏)的目的:顶部系统状态栏和App的导航栏一体化,不给用户突兀的感觉,使用户把更多的视角留在我们的App上. 沉浸式状态栏的兼容情况 Android版本 透明状 ...

  9. android 5.0状态栏下载地址,Android沉浸式状态栏(5.0以上系统)

    Android沉浸式状态栏(5.0以上系统) 沉浸式状态栏可以分为两种: 1.直接给状态栏设置颜色 (如下图:) 这里写图片描述 java代码形式: if (Build.VERSION.SDK_INT ...

最新文章

  1. Python 机器学习之项目实践
  2. Android 机型适配之gradient默认渐变方向
  3. java gzip xml_Java GZIPInputStream与GZIPOutputStream的使用示例
  4. 前端必读:浏览器内部工作原理
  5. OpenGL simpletexture简单的纹理的实例
  6. 超全整理 | 嵌入式Linux 性能工具和诊断思路
  7. BIM 360 Docs API在操作欧洲数据中心内容的一些调整
  8. 浏览器禁用Cookie,基于Cookie的会话跟踪机制失效的解决的方法
  9. 简单com编写流程及注册事项
  10. 运维自动化之5 - 基于LVS实现4层负载均衡应用
  11. 申请软著源程序量一般填多少
  12. 【VHDL】半减器和全减器的设计
  13. 第十章 隐马尔可夫模型
  14. BZOJ1597 [Usaco2008 Mar] 土地购买
  15. 解决“远程会话已断开连接,因为访问被拒绝导致许可证存储的创建失败,请使用提升的权限运行远程桌面客户端”问题...
  16. Serval and Rooted Tree(树形dp)
  17. android 特殊符号
  18. 获取微信运动 php,【小程序+ thinkphp5】 获取微信运动数据
  19. vue实现带样式的textarea输入框,contenteditable属性应用
  20. 综述:轻量级CNN架构设计

热门文章

  1. 性能监控—JMeter监控CPU和内存
  2. Xshell的使用Xftp的使用
  3. easeljs web开发围住神经小猫咪【一】
  4. Grid++Report数据/日期格式设置
  5. 百度业务运营部_数据分析师(产品运营)岗位要求详解(1)
  6. koa mysql_使用koa+mysql实现一个完整的项目
  7. SpringBoot入门到精通-三步整合knife4j
  8. 计算机系统的备份与还原实验报告,实验报告系统备份和恢复.doc
  9. [音乐]歌手萨顶顶及其专辑万物生
  10. Thinkphp6 使用composer 安装