Android 实现沉浸式状态栏(包含顶部栏吸顶Layout CoordinatorLayout实现沉 ...

打印 上一主题 下一主题

主题 686|帖子 686|积分 2058

前言

Android状态栏默认是固定的黑底白字,这肯定是不被巨大的设计师所喜欢的,更有甚者,某些时候设计盼望内容可以或许延伸到状态栏上部(例如顶部是大图的情况)。所幸的是随着Android版本的迭代,开辟者对状态栏等控件有了更多的控制。Android不停在尝试引入新的Api来满足开辟者的需求,但Api却不停不够完美,函数添加了许多,却都不够简单或者说完美,算上第三方厂商的特色行为,怎一个“乱”字了得。
Android 完美的沉浸式需要多个函数共同使用才能完成,我们这里可以直接使用ImmersionBar 框架来实现沉浸式状态栏。
这里分为两部分:第一部分是平凡的Layout实现沉浸式状态栏(如:FrameLayout、LinearLayout、RelativeLayout、ConstraintLayout),
第二部分是特殊的Layout实现沉浸式状态栏(如:CoordinatorLayout实现沉浸式状态栏)。


1.引入immersionbar依赖,在app的build.gradle中添加依赖
  1.     //沉浸式状态栏框架导入
  2.     // 基础依赖包,必须要依赖
  3.     api "com.geyifeng.immersionbar:immersionbar:3.2.2"
  4.     // kotlin扩展(可选)
  5.     api "com.geyifeng.immersionbar:3.2.2"
复制代码
在项目的build.gradle下的repositories添加(新版本Android Studio创建的项目是在settings.gradle下的repositories),并同步项目。
  1. mavenCentral()
复制代码
关于全面屏
在manifest的application节点下加入
  1. <meta-data
  2.      android:name="android.max_aspect"
  3.      android:value="2.4" />
复制代码
关于刘海屏
在manifest的application节点下加入
  1.    <!--适配华为(huawei)刘海屏-->
  2.    <meta-data
  3.      android:name="android.notch_support"
  4.      android:value="true"/>
  5.    <!--适配小米(xiaomi)刘海屏-->
  6.    <meta-data
  7.      android:name="notch.config"
  8.      android:value="portrait|landscape" />
复制代码

2.平凡的Layout实现沉浸式状态栏。
1)在res文件夹下的values文件夹下的styles.xml文件内加入
  1.     <!-- Base application theme. -->
  2.     <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
  3.         <!-- Customize your theme here. -->
  4.         <item name="colorPrimary">@color/colorPrimary</item>
  5.         <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
  6.         <item name="colorAccent">@color/colorAccent</item>
  7.         <item name="android:windowContentOverlay">@null</item>
  8.         <item name="android:windowBackground">@android:color/white</item>
  9.     </style>
复制代码
然后在manifest的application节点上加入android:theme="@style/AppTheme"(也可以在activity节点上加入,但是如许一来每个用到沉浸式状态栏的Activity都要加一下这个属性了),如下图一


2)在xml写一个标题栏Layout,不要给外层Layout设置android:fitsSystemWindows="true"属性,然后设置了第3步这个标题栏Layout就可以或许延伸到状态栏底部。
  1.         <androidx.appcompat.widget.Toolbar
  2.             android:id="@+id/toolbar"
  3.             android:layout_width="match_parent"
  4.             android:layout_height="@dimen/dp_73"
  5.             android:background="@color/color_FF198CFF"
  6.             android:minHeight="?attr/actionBarSize"
  7.             android:orientation="vertical"
  8.             app:contentInsetStart="0dp">
  9.             <LinearLayout
  10.                 android:layout_width="match_parent"
  11.                 android:layout_height="@dimen/dp_73"
  12.                 android:orientation="vertical">
  13.                 <View
  14.                     android:layout_width="match_parent"
  15.                     android:layout_height="@dimen/dp_25" />
  16.                 <FrameLayout
  17.                     android:layout_width="match_parent"
  18.                     android:layout_height="@dimen/dp_48">
  19.                     <FrameLayout
  20.                         android:id="@+id/layout_back"
  21.                         android:layout_width="@dimen/dp_36"
  22.                         android:layout_height="match_parent"
  23.                         android:gravity="start"
  24.                         tools:ignore="UselessParent">
  25.                         <ImageView
  26.                             android:id="@+id/imv_back"
  27.                             android:layout_width="@dimen/dp_6"
  28.                             android:layout_height="@dimen/dp_11"
  29.                             android:layout_gravity="center"
  30.                             android:src="@mipmap/icon_arrowhead_left"
  31.                             tools:ignore="ContentDescription" />
  32.                     </FrameLayout>
  33.                     <TextView
  34.                         android:id="@+id/tev_title"
  35.                         android:layout_width="match_parent"
  36.                         android:layout_height="@dimen/dp_48"
  37.                         android:gravity="center"
  38.                         android:text="@string/android_and_js"
  39.                         android:textColor="@color/white"
  40.                         android:textSize="@dimen/sp_20" />
  41.                 </FrameLayout>
  42.             </LinearLayout>
  43.         </androidx.appcompat.widget.Toolbar>
复制代码
3)封装immersionbar框架中的沉浸式状态栏方法
  1. protected open fun setToolbar(isDarkFont: Boolean, color: Int) {
  2.         if (isDarkFont) {
  3.             ImmersionBar.with(this) //原理:如果当前设备支持状态栏字体变色,会设置状态栏字体为黑色,如果当前设备不支持状态栏字体变色,会使当前状态栏加上透明度,否则不执行透明度
  4.                 .statusBarDarkFont(isDarkFont)
  5.                 .statusBarColor(color) //状态栏颜色,不写默认透明色
  6.                 //                    .autoStatusBarDarkModeEnable(true, 0.2f) //自动状态栏字体变色,必须指定状态栏颜色才可以自动变色哦
  7.                 .init()
  8.         } else {
  9.             ImmersionBar.with(this)
  10.                 .statusBarDarkFont(isDarkFont)
  11.                 .statusBarColor(color) //状态栏颜色,不写默认透明色
  12.                 //                    .autoStatusBarDarkModeEnable(true, 0.2f) //自动状态栏字体变色,必须指定状态栏颜色才可以自动变色哦
  13.                 .init()
  14.         }
  15.     }
复制代码
  1. 在Activity中调用这个方法(参数一:是否是深色字体的;参数二:沉浸状态栏的颜色)
复制代码
  1. setToolbar(false, R.color.color_FF198CFF)
复制代码

3.第二步的方法中能实现绝大多数沉浸式状态栏,然而不能实现顶部栏吸顶Layout CoordinatorLayout的沉浸式状态栏。
下面我们来看一下CoordinatorLayout实现沉浸式状态栏
1)在res文件夹下的values文件夹下的styles.xml文件内加入
  1.     <style name="NoActionBarTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
  2.         <!-- Customize your theme here. -->
  3.         <item name="colorPrimary">@color/colorPrimary</item>
  4.         <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
  5.         <item name="colorAccent">@color/colorAccent</item>
  6.         <!-- 启动白屏解决方案,这三行是重点 -->
  7.         <!--   设置背景,解决白屏的关键   -->
  8.         <!-- 将splash图片设置在这,这样这张图片取代白屏 -->
  9.         <item name="android:windowBackground">@drawable/picture3</item>
  10.         <!-- 设置状态栏为白色的,状态栏文字为黑的 -->
  11.         <item name="android:statusBarColor" tools:targetApi="l">@color/white</item>
  12.         <item name="android:windowLightStatusBar" tools:targetApi="m">true</item>
  13.     </style>
复制代码
然后在manifest的application节点下的activity节点上加入android:theme="@style/NoActionBarTheme",如下图一

 2)在xml写一个Layout,不要给外层Layout设置android:fitsSystemWindows="true"属性,然后设置了第3步这个标题栏Layout就可以或许延伸到状态栏底部。
  1.             <androidx.coordinatorlayout.widget.CoordinatorLayout
  2.                 android:layout_width="match_parent"
  3.                 android:layout_height="match_parent"
  4.                 android:clipToPadding="true">
  5.                 <com.google.android.material.appbar.AppBarLayout
  6.                     android:id="@+id/app_bar_layout"
  7.                     android:layout_width="match_parent"
  8.                     android:layout_height="wrap_content">
  9.                     <com.google.android.material.appbar.CollapsingToolbarLayout
  10.                         android:id="@+id/collapsing_toolbar_layout"
  11.                         android:layout_width="match_parent"
  12.                         android:layout_height="wrap_content"
  13.                         app:layout_scrollFlags="scroll|exitUntilCollapsed">
  14.                         <ImageView
  15.                             android:id="@+id/imv_banner"
  16.                             android:layout_width="match_parent"
  17.                             android:layout_height="@dimen/dp_270"
  18.                             android:scaleType="centerCrop"
  19.                             android:src="@mipmap/picture_manami_enosawa2"
  20.                             tools:ignore="ContentDescription" />
  21.                         <androidx.appcompat.widget.Toolbar
  22.                             android:layout_width="match_parent"
  23.                             android:layout_height="@dimen/dp_73"
  24.                             app:contentInsetStart="0dp"
  25.                             app:layout_collapseMode="pin" />
  26.                     </com.google.android.material.appbar.CollapsingToolbarLayout>
  27.                     <FrameLayout
  28.                         android:layout_width="match_parent"
  29.                         android:layout_height="@dimen/dp_50"
  30.                         android:orientation="vertical"
  31.                         tools:ignore="UselessLeaf">
  32.                         <net.lucode.hackware.magicindicator.MagicIndicator
  33.                             android:id="@+id/magic_indicator"
  34.                             android:layout_width="wrap_content"
  35.                             android:layout_height="@dimen/dp_40"
  36.                             android:layout_gravity="center" />
  37.                     </FrameLayout>
  38.                 </com.google.android.material.appbar.AppBarLayout>
  39.                 <androidx.viewpager.widget.ViewPager
  40.                     android:id="@+id/view_pager"
  41.                     android:layout_width="match_parent"
  42.                     android:layout_height="match_parent"
  43.                     app:layout_behavior="@string/appbar_scrolling_view_behavior" />
  44.             </androidx.coordinatorlayout.widget.CoordinatorLayout>
复制代码
3)封装immersionbar框架中的沉浸式状态栏方法
  1.     /**
  2.      * 顶部栏吸顶专用
  3.      */
  4.     protected open fun setToolbar2(
  5.         isDarkFont: Boolean,
  6.         statusBarColor: Int
  7.     ) {
  8.         if (isDarkFont) {
  9.             val window = window
  10.             window.clearFlags(
  11.                 WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
  12.                         or WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION
  13.             )
  14.             window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
  15.                     or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
  16.                     or View.SYSTEM_UI_FLAG_LAYOUT_STABLE)
  17.             window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
  18.             window.statusBarColor = Color.TRANSPARENT
  19.             //        window.setNavigationBarColor(Color.TRANSPARENT);
  20.             ImmersionBar.with(this) //原理:如果当前设备支持状态栏字体变色,会设置状态栏字体为黑色,如果当前设备不支持状态栏字体变色,会使当前状态栏加上透明度,否则不执行透明度
  21.                 .statusBarDarkFont(isDarkFont)
  22.                 .statusBarColor(statusBarColor) //状态栏颜色,不写默认透明色
  23.                 //                    .autoStatusBarDarkModeEnable(true, 0.2f) //自动状态栏字体变色,必须指定状态栏颜色才可以自动变色哦
  24.                 .keyboardEnable(true)
  25.                 .init()
  26.         } else {
  27.             ImmersionBar.with(this) //原理:如果当前设备支持状态栏字体变色,会设置状态栏字体为黑色,如果当前设备不支持状态栏字体变色,会使当前状态栏加上透明度,否则不执行透明度
  28.                 .statusBarDarkFont(isDarkFont)
  29.                 .statusBarColor(statusBarColor) //状态栏颜色,不写默认透明色
  30.                 //                    .autoStatusBarDarkModeEnable(true, 0.2f) //自动状态栏字体变色,必须指定状态栏颜色才可以自动变色哦
  31.                 .keyboardEnable(true)
  32.                 .init()
  33.             val window = window
  34.             window.clearFlags(
  35.                 WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
  36.                         or WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION
  37.             )
  38.             window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
  39.                     or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
  40.                     or View.SYSTEM_UI_FLAG_LAYOUT_STABLE)
  41.             window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
  42.             window.statusBarColor = Color.TRANSPARENT
  43.             //        window.setNavigationBarColor(Color.TRANSPARENT);
  44.         }
  45.     }
复制代码
在Activity中调用这个方法(参数一:是否是深色字体的;参数二:沉浸状态栏的颜色),如许就实现了CoordinatorLayout的沉浸式状态栏,如以下视频(这里的沉浸状态栏的颜色设置的完全透明,上滑的时候会渐变至纯白色)。
  1. setToolbar2(false, R.color.color_transparent):
复制代码
    Android顶部栏吸顶结果
  
 
如对此有疑问,请接洽qq1164688204。
推荐Android开源项目
项目功能介绍:本来是RxJava2和Retrofit2项目,现已更新使用Kotlin+RxJava2+Retrofit2+MVP架构+组件化和 Kotlin+Retrofit2+协程+MVVM架构+组件化,添加自动管理token 功能,添加RxJava2 生命周期管理,集成极光推送、阿里云Oss对象存储和高德地图定位功能。
项目地址:https://gitee.com/urasaki/RxJava2AndRetrofit2

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

去皮卡多

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表