状态栏 导航栏 和 action bar的样式设定

逃离我推掉我的手 2022-05-28 08:14 281阅读 0赞

透明状态栏

透明状态栏一般用在有背景图片的页面中。

S1.png_raw_true

这种情况我们可能希望顶部的状态栏从蓝色变为透明。

想实现这个可以设定: android:windowTranslucentStatus 这个属性

  1. <item name="android:windowTranslucentStatus">true</item>

不过这个属性是从 SDK V21 才加上的,所以我们需要建一个values-v21文件夹,在这个文件夹中定义一个 styles.xml 加上刚才提到的属性。 比如这样:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <resources>
  3. <style name="AppTheme.NoActionBar">
  4. <item name="windowActionBar">false</item>
  5. <item name="windowNoTitle">true</item>
  6. <item name="android:windowTranslucentStatus">true</item>
  7. </style>
  8. </resources>

这样实现的效果为: S2.png_raw_true

在顶端状态栏的部分,你会发现蓝色的占了一部分,半透明的占了一部分。 这是因为,在layout的xml文件中ImageView这个控件默认是放到了status bar的下面,因此他不会占用status bar的区域,这样就导致了 status bar 的颜色还是蓝色(colorPrimaryDark定义),而网上滚动了一段距离之后,蓝色的占了一部分、背景图片占了一部分高度。

想完全去掉蓝色部分,让ImageView完全占有status bar的高度,可以给ImageView添加下面的一个属性fitsSystemWindows=true:

  1. <ImageView
  2. android:layout_width="match_parent"
  3. android:layout_height="match_parent"
  4. android:scaleType="centerCrop"
  5. app:layout_collapseMode="parallax"
  6. android:fitsSystemWindows="false" <!-- 重点在这个属性 -->
  7. android:src="@drawable/x2" />

这样运行就可以看到这样的效果: S3.png_raw_true

会看到已经没有蓝色的状态栏了,ImageView 已经完全使用了status bar的空间。 向上滑动,折叠之后你会看到折叠之后带action bar的效果: S4.png_raw_true

你可能会问:

  1. ImageView现在位于status bar半透明栏的下面,能不能让status bar全透明?
  2. 折叠之后,能不能保留ImageView作为背景?

第一点这样来做, 在Activity的onCreate方法中加上这段代码:

  1. @Override
  2. protected void onCreate(Bundle savedInstanceState) {
  3. super.onCreate(savedInstanceState);
  4. // Start here
  5. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  6. Window window = getWindow();
  7. window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
  8. window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
  9. | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
  10. window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
  11. window.setStatusBarColor(Color.TRANSPARENT);
  12. }
  13. // End here
  14. ...
  15. }

运行效果如下: S5.png_raw_true

第二点这样来做,在v21/styles.xml里面加上colorPrimary / colorPrimaryDark 的透明色设定:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <resources>
  3. <style name="AppTheme.NoActionBar">
  4. <item name="windowActionBar">false</item>
  5. <item name="windowNoTitle">true</item>
  6. <item name="android:windowTranslucentStatus">true</item>
  7. <item name="colorPrimary">@android:color/transparent</item>
  8. <item name="colorPrimaryDark">@android:color/transparent</item>
  9. </style>
  10. </resources>

你可能会说:我已经定义过这两个颜色了啊。 是的,在values/styles.xml里面, 通常情况下我们已经定义过这两个颜色色值了,否则我们也不会看到上面截图中的蓝色。当我们将这两个颜色设定为 transparent 之后,status bar (对应的是 colorPrimratyDark) 和 action bar(对应的是 colorPrimrary)就都是透明的了,所以在折叠之后显示status bar 和 action bar的时候 就可以看到ImageView的图片了。 运行效果如下: S6.png_raw_true

颜色状态栏

如果背景不是图片而是颜色填充则更加适合。 这个你应该已经想到了,改变 colorPrimrary / colorPrimraryDark.

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <resources>
  3. <style name="AppTheme.NoActionBar">
  4. <item name="windowActionBar">false</item>
  5. <item name="windowNoTitle">true</item>
  6. <item name="android:windowTranslucentStatus">true</item>
  7. <item name="colorPrimary">@android:color/holo_orange_light</item>
  8. <item name="colorPrimaryDark">@android:color/holo_orange_dark</item>
  9. </style>
  10. </resources>

然后运行是这个效果: S7.png_raw_true

你可能会问,怎么 status bar 和 action bar 的颜色是一样的? 这是一个好问题,我们明明设定了status bar的颜色为更深的颜色,现在运行起来怎么是一样的呢?原因是因为我们在刚才的 Activity#onCreate 里面加了这段代码:

  1. @Override
  2. protected void onCreate(Bundle savedInstanceState) {
  3. super.onCreate(savedInstanceState);
  4. // Start here
  5. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  6. Window window = getWindow();
  7. window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
  8. window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
  9. | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
  10. window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
  11. window.setStatusBarColor(Color.TRANSPARENT);
  12. }
  13. // End here
  14. ...
  15. }

这段代码导致了status bar为全透明,所以status bar的颜色跟 action bar的颜色一样了。

我们注释掉这段代码再来一次。效果是这样的: S8.png_raw_true

我知道你又要说status bar的颜色跟设定的颜色还是不一样,看起来像是半透明的感觉。 你说的对,这是因为在 v21/styles.xml 里面我们设定了 <item name="android:windowTranslucentStatus">true</item> 去掉他,再运行一次,结果就如我们期望的那样了: S9.png_raw_true

可折叠action bar

上述的效果中,默认是action bar是不显示的,或者说不是以非常明显的方式来显示,而是一个展开的样式,在向上滑动之后折叠成了action bar,这是CoordinatorLayout实现,待仔细研究。

透明导航栏 & 导航栏颜色

上面的这些截图当中,底部的导航栏都是黑色背景,而我们在某种阅读场景下可能会想知道如何把导航栏也设定为透明的,用下面的代码可以设定为半透明样式, 还是在 v21/styles.xml,加上这段代码:

  1. <item name="android:windowTranslucentNavigation">true</item>

就可以实现这样的效果: S10.png_raw_true

类似的,如果我们想要改变导航栏的颜色,这样来设定:

  1. <!-- 设定颜色时不能为透明, 所以设定为false -->
  2. <item name="android:windowTranslucentNavigation">false</item>
  3. <item name="android:navigationBarColor">@color/colorAccent</item>

注: colorAccent 是在colors.xml里面定义的:

  1. <color name="colorAccent">#FF4081</color>

运行效果如下: S11.png_raw_true

代码下载 (https://github.com/chinalwb/AE/tree/master/summaryOfMine/statusbar_navigationbar_actionbar)

水平有限,如有不正确的地方,请您指出,谢谢。

发表评论

表情:
评论列表 (有 0 条评论,281人围观)

还没有评论,来说两句吧...

相关阅读