安卓android一种沉浸式状态栏和导航栏并可设置渐变和图片的方法

安卓android一种沉浸式状态栏和导航栏并可设置渐变和图片的方法

介绍

网络上流传的状态栏导航栏沉浸的方式有很多,但是在我使用的时候都失效了,在官网也没找到合适的例子达到期望,根据情况判断是由于目前版本过新和系统有关系。
也许是自己太菜的缘故。
然后就后面自己摸索出来的一种方式,在亲身使用有效后在这里记录一下。
先列出目前我使用的相关版本:


gradle plugin version: 7.2.1
gradle version: 7.3.3
android studio version: Chipmunk 2021.2.1
compileSdk 32
targetSdk 32

过程

这里还是粗略记录一下过程,结果在最后面。

首先,放出刚开始的界面情况:

然后是基本的配色,方便对比结果:


<style name="Colors" parent="Theme.Material3.DayNight">
 <!--基本配色,@color就不放了,自己之后随意替换一些颜色就好-->
 <item name="colorPrimary">#1193C2</item>
 <item name="colorPrimaryVariant">#02719F</item>
 <item name="colorOnPrimary">@color/white</item>
 <item name="colorSecondary">@color/pink_3</item>
 <item name="colorSecondaryVariant">@color/pink_2</item>
 <item name="colorOnSecondary">@color/black</item>
 <item name="android:statusBarColor">@color/blue_1</item>
 <item name="android:navigationBarColor">@android:color/white</item>
</style>

沉浸系统栏的话,透明是必不可少的,在这里也要把默认ActionBar禁用换成ToolBar,这里就是先设置好主题为透明主题:


<style name="NoActionBarAndTransparent" parent="Colors">
 <!--这里不能使用直接设置透明颜色的,要用那个window颜色的,不然导航栏颜色会没法改变到-->
 <!-- <item name="android:statusBarColor">@android:color/transparent</item>-->
 <!-- <item name="android:navigationBarColor">@android:color/transparent</item>-->
 <item name="android:windowIsTranslucent">true</item>
 <item name="android:windowTranslucentStatus">true</item>
 <item name="android:windowTranslucentNavigation">true</item>
 <!-- <item name="android:windowDrawsSystemBarBackgrounds">true</item>-->
 <item name="windowActionBar">false</item>
 <item name="windowNoTitle">true</item>
</style>

这里放出布局:


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:app="http://schemas.android.com/apk/res-auto"
 android:id="@+id/main_layout_container"
 android:layout_width="match_parent"
 android:layout_height="match_parent">
 <com.google.android.material.appbar.AppBarLayout
 android:id="@+id/main_appbar"
 android:layout_width="match_parent"
 android:layout_height="wrap_content">
 <androidx.appcompat.widget.Toolbar
 android:id="@+id/main_toolbar"
 style="@style/Widget.MaterialComponents.Toolbar.Primary"
 android:layout_width="match_parent"
 android:layout_height="?attr/actionBarSize"
 app:title="沉浸测试" />
 </com.google.android.material.appbar.AppBarLayout>
 <androidx.recyclerview.widget.RecyclerView
 android:id="@+id/main_recycler"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:layout_below="@id/main_appbar" />
</RelativeLayout>

结果图如下,状态栏和导航栏透明算是完成了,至于toolBar的颜色只需要设置background透明就好。

在appBar和toolBar上加:android:background="@android:color/transparent",就能获得全白的界面(因为文字也是白色),好吧toolBar属性再加上一个app:titleTextColor="@color/black"
得到如下结果:

这时候透明工作已经完成,剩下的就是着色?差不多吧。

这里放到一个方法里,名字随意,就暂定underBar这样,主要用到的就是这个window.setBackgroundDrawable


fun underBar(activity: Activity) {
 //暂时设置为亮灰色看看情况
 activity.window.setBackgroundDrawable(ColorDrawable(Color.LTGRAY))
}

在需要的地方调用,比如activity的onCreate()中,看效果:

界面全部变成灰色了,沉浸嘛,不至于主要界面颜色也跟着沉浸了,这样背景设置个图片情况就很怪了:


//改变下方法
fun underBar(activity: Activity, drawable: Drawable) {
 activity.window.setBackgroundDrawable(drawable)
}

//调用
underBar(activity, AppCompatResources.getDrawable(activity, R.drawable.ic_background)!!)

结果:

优化下方法,让主要内容部分还是原来的颜色。此外,暗色图片导致界面内容颜色不明显了,换个亮色的吧。

这里涉及到改变相关内容字体颜色啊什么的,还有这样使用的背景图片有变形的可能,可以通过获取屏幕宽高来裁切个背景就好,这里只提供个思路,可能会用到,到时候再说,扯远了。


//改变下方法,多了个内容View,就中间那块
fun underBar(
 activity: Activity,
 drawable: Drawable,
 contentView: View
) {
 val old = activity.window.decorView.background
 activity.window.setBackgroundDrawable(drawable)
 contentView.background = old
}

//调用,这里用了viewBinding所以可以这样传,怎么用可以看前面发过的有个MVVM使用笔记里面有
underBar(
 activity,
 AppCompatResources.getDrawable(activity, R.drawable.ic_background)!!,
 bind.mainRecycler
)

结果:

到这里,效果基本上还是没问题了,至于渐变色,只需要新建一个shape,来个例子,名字为shape_background.xml,没毛病:


<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
 <!--angle:旋转度数-->
 <gradient
 android:angle="0"
 android:endColor="#FF626E"
 android:startColor="#FFBE71" />
</shape>

//调用,改一个背景参数
underBar(
 activity,
 AppCompatResources.getDrawable(activity, R.drawable.shape_background)!!,
 bind.mainRecycler
)

结果:

结束

  1. 设置主题透明并换成toolBar,其实默认actionBar也行,就改成透明背景而已,所以用的时候看情况喽:

    
     <style name="NoActionBarAndTransparent" parent="Colors">
     <!--这里不能使用直接设置透明颜色的,要用那个window颜色的,不然导航栏颜色会没法改变到-->
     <!-- <item name="android:statusBarColor">@android:color/transparent</item>-->
     <!-- <item name="android:navigationBarColor">@android:color/transparent</item>-->
     <item name="android:windowIsTranslucent">true</item>
     <item name="android:windowTranslucentStatus">true</item>
     <item name="android:windowTranslucentNavigation">true</item>
     <!-- <item name="android:windowDrawsSystemBarBackgrounds">true</item>-->
     <item name="windowActionBar">false</item>
     <item name="windowNoTitle">true</item>
     </style>
    
  2. 代码:

    
     //改变下方法,多了个内容View,就中间那块
     fun underBar(
     activity: Activity,
     drawable: Drawable,
     contentView: View
     ) {
     val old = activity.window.decorView.background
     activity.window.setBackgroundDrawable(drawable)
     contentView.background = old
     }
    
  3. 调用:

    
     //调用,这里用了viewBinding所以可以这样传,怎么用可以看前面发过的有个MVVM使用笔记里面有
     underBar(
     activity,
     AppCompatResources.getDrawable(activity, R.drawable.ic_background)!!,
     bind.mainRecycler
     )
    

有帮助到you不妨赞赞俺,谢谢。

作者:heue

%s 个评论

要回复文章请先登录注册