android沉浸状态栏工具,Android 沉浸式状态栏 渐变颜色的实现

原标题:Android 沉浸式状态栏 渐变颜色的实现

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

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

23493adfdb431aee45d5f836e647f67c.png

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

纯色兼容状态栏

b7a07e6d56a2259f2ec16bce8b878220.png

代码如下

/**

* 设置状态栏颜色

*

* @paramactivity 需要设置的activity

* @paramcolor 状态栏颜色值

* @paramstatusBarAlpha 状态栏透明度

*/

publicstaticvoidsetColor(Activity activity, @ColorInt intcolor, @IntRange(from = 0, to = 255)intstatusBarAlpha){

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));

} elseif(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(计算状态栏颜色)/**

* 计算状态栏颜色

*

* @paramcolor color值

* @paramalpha alpha值

* @return最终的状态栏颜色

*/

privatestaticintcalculateStatusColor(@ColorInt intcolor, intalpha){

if(alpha == 0) {

returncolor;

}

floata = 1- alpha / 255f;

intred = color >> 16& 0xff;

intgreen = color >> 8& 0xff;

intblue = color & 0xff;

red = ( int) (red * a + 0.5);

green = ( int) (green * a + 0.5);

blue = ( int) (blue * a + 0.5);

return0xff<< 24| red << 16| green << 8| blue;

}

自定义View状态栏/**

* 自定义View状态栏

*

* @paramactivity 需要设置的activity

* @paramcolor 状态栏颜色值

* @paramalpha 透明值

* @return状态栏矩形条

*/

privatestaticView createStatusBarView(Activity activity, @ColorInt intcolor, intalpha){

// 绘制一个和状态栏一样高的矩形

View statusBarView = newView(activity);

LinearLayout.LayoutParams params =

newLinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(activity));

statusBarView.setLayoutParams(params);

statusBarView.setBackgroundColor(calculateStatusColor(color, alpha));

//自定义的StatusBarView的Id

statusBarView.setId(FAKE_STATUS_BAR_VIEW_ID);

returnstatusBarView;

}

最后重新规划布局

setRootView/**

* 设置根布局参数

*/

privatestaticvoid 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 instanceofViewGroup) {

childView.setFitsSystemWindows( true);

((ViewGroup) childView).setClipToPadding( true);

}

}

}

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

//设置纯色状态栏

StatusBarUtil.setColor( this, AppUtils.getColor(R.color.colorPrimary));

渐变色兼容状态栏

2e6ca8cd1f45ad938e8ccd9d9593c944.png

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

代码如下

/**

* 为界面设置自定义透明View

*

* @param activity 需要设置的activity

* @param statusBarAlpha 状态栏透明度

* @param needOffsetView 需要向下偏移的 View

public static void setTranslucentForWindow(Activity activity, @IntRange(from = 0, to = 255) intstatusBarAlpha,

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,自定义id

View 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/**

* 获取状态栏高度

*

* @paramcontext context

* @return状态栏高度

*/

publicstaticintgetStatusBarHeight(Context context){

// 获得状态栏高度

intresourceId = context.getResources().getIdentifier( "status_bar_height", "dimen", "android");

returncontext.getResources().getDimensionPixelSize(resourceId);

}

setTransparentForWindow/**

* 设置透明

*/

publicstaticvoidsetTransparentForWindow(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);

} elseif(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 透明值

*/

privatestaticvoidaddTranslucentView(Activity activity, @IntRange(from= 0, to = 255) intstatusBarAlpha){

ViewGroup contentView = (ViewGroup) activity.findViewById(android.R.id.content); //系统Id

View 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);

//布局如下

xmlns: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:layout_width="match_parent"

android:layout_height="wrap_content"

android:background="@drawable/shape_gradient"

android:theme="@style/AppTheme.AppBarOverlay"

app:elevation="@dimen/dp0">

android: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">

至此,渐变色状态栏的配置已经介绍完全了,说实话刚开始做的时候,还真的没想到用自定义View延伸到状态栏中显示,但细想下纯色状态栏中的实现也有类似的操作,再结合一下就实现了兼容上下版本的效果

个人博客地址:https://ye-miao.github.io/

责任编辑:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值