android_基础_半透明status bar和系统navigation bar

121 篇文章 1 订阅

状态栏汇总

透明化状态栏(推荐)

转载自: https://www.jianshu.com/p/e89ee0a77bb5

关于如何实现Android透明状态栏的总结

=====================

建议: activity中调用下文setStatusBarFullTransparent()方法透明化
然后找到toolbar设置fitsSystemWindows = true使内容插入statusbar

开门见山。
原来做的效果,如下图(顶部有一条明显的橙色状态栏):

在这里插入图片描述

改过之后(顶部状态栏是透明的):

在这里插入图片描述

我发现网上写的一些文章,不够简洁明了,我整理了一下,复制粘贴一下就可以在项目中运用。

首先,在你的Activity中添加下面四个方法(或者封装在一个工具类中)

       /**
         * 全透状态栏
         */
        protected void setStatusBarFullTransparent() {
            if (Build.VERSION.SDK_INT >= 21) {//21表示5.0
                Window window = getWindow();
                window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
                window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
                window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
                window.setStatusBarColor(Color.TRANSPARENT);
            } else if (Build.VERSION.SDK_INT >= 19) {//19表示4.4
                getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
                //虚拟键盘也透明
                //getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
            }
        }
    
        /**
         * 半透明状态栏
         */
        protected void setHalfTransparent() {
    
            if (Build.VERSION.SDK_INT >= 21) {//21表示5.0
                View decorView = getWindow().getDecorView();
                int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
                decorView.setSystemUiVisibility(option);
                getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
    
            } else if (Build.VERSION.SDK_INT >= 19) {//19表示4.4
                getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
                //虚拟键盘也透明
                // getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
            }
        }
    
        /**
         * 如果需要内容紧贴着StatusBar
         * 应该在对应的xml布局文件中,设置根布局fitsSystemWindows=true。
         */
        private View contentViewGroup;
    
        protected void setFitSystemWindow(boolean fitSystemWindow) {
            if (contentViewGroup == null) {
                contentViewGroup = ((ViewGroup) findViewById(android.R.id.content)).getChildAt(0);
            }
            contentViewGroup.setFitsSystemWindows(fitSystemWindow);
        }
    
        /**
         * 为了兼容4.4的抽屉布局->透明状态栏
         */
        protected void setDrawerLayoutFitSystemWindow() {
            if (Build.VERSION.SDK_INT == 19) {//19表示4.4
                int statusBarHeight = getStatusHeight(this);
                if (contentViewGroup == null) {
                    contentViewGroup = ((ViewGroup) findViewById(android.R.id.content)).getChildAt(0);
                }
                if (contentViewGroup instanceof DrawerLayout) {
                    DrawerLayout drawerLayout = (DrawerLayout) contentViewGroup;
                    drawerLayout.setClipToPadding(true);
                    drawerLayout.setFitsSystemWindows(false);
                    for (int i = 0; i < drawerLayout.getChildCount(); i++) {
                        View child = drawerLayout.getChildAt(i);
                        child.setFitsSystemWindows(false);
                        child.setPadding(0,statusBarHeight, 0, 0);
                    }
    
                }
            }
        }

然后,在Activity的onCreate()方法中调用即可。示例如下

Activity
    public class TestActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_test);
    
            setHalfTransparent();
            setFitSystemWindow(false);
        }
    
        protected void setHalfTransparent()...
        protected void setStatusBarFullTransparent()...
        protected void setFitSystemWindow()...
        protected void setDrawerLayoutFitSystemWindow()...
    }
   
布局文件
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout android:id="@+id/drawerLayout"
                  xmlns:android="http://schemas.android.com/apk/res/android"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"
                  android:background="@drawable/bg_start">
    
    
        <Button
            android:id="@+id/button"
            android:layout_width="100dp"
            android:layout_height="40dp"
            android:layout_marginLeft="50dp"
            android:background="#F86254"
            android:text="button"
            android:textColor="@color/white" />
    
    </LinearLayout>
1.未做任何设置

可见,Android5.0以上由于默认是Material Design,顶部是蓝色状态栏。而5.0以下,默认都是黑色,而且无法修改。

在这里插入图片描述

2.半透明状态栏,fitsSystemWindows=false
    @Override
    public void init(Bundle savedInstanceState) {
        setHalfTransparent();
        setFitSystemWindow(false);
    }

在这里插入图片描述

可见,5.0以上蓝色状态栏没了,变成了半透明的黑色,而内容区域则有了全屏的效果。
但是也要知道一点,那个红色的TextView,原来是紧贴着状态栏,现在是紧贴着屏幕的上边缘,这样就导致,内容被遮挡。解决这个问题需要一个关键的属性是setFitSystemWindow=true,追踪源码可知,它可以让我们的布局,paddingTop等于状态栏的高度,这样红色TextView的位置就会向下移,从而不会被遮挡。

3.半透明状态栏,fitsSystemWindows=true
    @Override
    public void init(Bundle savedInstanceState) {
        setHalfTransparent();
        setFitSystemWindow(true);
    }

此时红色的TextView,位于状态栏下方。

4.全透明状态栏,fitsSystemWindows=false
    setStatusBarFullTransparent();
    setFitSystemWindow(false);

在这里插入图片描述
全透明和半透明的区别在于,状态栏是否具有淡黑色的背景,根据项目需求合理运用。

5.全透明状态栏,fitsSystemWindows=true
    setStatusBarFullTransparent();
    setFitSystemWindow(true);

在这里插入图片描述

6.DrawerLayout如何使用

直接使用上述方式,在4.4系统上会出现异常,因此我们需要进行适配。
修改xml文件,DrawerLayout需要添加fitsSystemWindows和clipToPadding属性,DrawerLayout布局里的一级布局,都需设置fitsSystemWindows=true。

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.v4.widget.DrawerLayout android:id="@+id/drawerLayout"
                                            xmlns:android="http://schemas.android.com/apk/res/android"
                                            android:layout_width="match_parent"
                                            android:fitsSystemWindows="true"
                                            android:clipToPadding="false"
                                            android:layout_height="match_parent">
    
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:fitsSystemWindows="true"
            android:background="@drawable/bg_start"
            android:orientation="vertical">
    
    
            <Button
                android:id="@+id/button"
                android:layout_width="100dp"
                android:layout_height="wrap_content"
                android:background="#F86254"
                android:text="show"
                android:textColor="@color/white" />
    
        </RelativeLayout>
    
        <FrameLayout
            android:id="@+id/sideLayout"
            android:layout_width="300dp"
            android:fitsSystemWindows="true"
            android:layout_height="match_parent"
            android:layout_gravity="end"
            android:background="@drawable/bg_test">
    
            <Button
                android:layout_width="100dp"
                android:layout_height="30dp"
                android:background="#F86254"
                android:text="button"
                android:textColor="@color/white" />
        </FrameLayout>
    
    </android.support.v4.widget.DrawerLayout>
  1. 全透明状态栏,
	fitsSystemWindows=false
    setStatusBarFullTransparent();

在这里插入图片描述

  1. DrawerLayout全透明状态栏,fitsSystemWindows=true
    setStatusBarFullTransparent();
    setDrawerLayoutFitSystemWindow();

在这里插入图片描述

7.可能会错误的地方

本来我们有一个界面:

在这里插入图片描述

然后按照上面的,添加了代码之后

    setStatusBarFullTransparent();
    setFitSystemWindow(true);

在这里插入图片描述

这是什么鬼!!!
说好的透明状态栏呢,怎么状态栏背景色是白色的!

确实是全屏了,状态栏也透明了,只是由于,根布局没设置背景色,默认的背景色白色,所以你看到的灰色状态栏底色,其实是根布局的TopPadding。

在这里插入图片描述

8.Activity中嵌套了Fragment,如何使用

另附一张效果图:

在这里插入图片描述

在Activity中设置setStatusBarFullTransparent(),然后在fragment的xml文件中(这边写的粗糙,应该在代码中,获取StatusBar高度然后设置paddingTop):

在这里插入图片描述

有兴趣可以可以琢磨一下,为什么这么写,正所谓:学而不思则罔,思而不学则殆。

9.问题

这个方案总体来说其实不是很好,会导致过度绘制,如果对性能要求不是很严苛,可以选择该方案。

透明状态栏(StatusBar)的全适配

状态栏指定android手机上顶部显示手机状态信息的位置。

透明状态栏是android 自4.4开始新加入的功能,他可以是状态栏根据我们自己想要的颜色进行定义,使titleBar能够和状态栏融为一体,增加沉浸感。

咱们需要对不同的版本适配StatusBar,下面咱们一个一个看

values/styles.xml

<resources>
  <style name="Theme.AppTheme.TranslucentStatusBar" parent="Theme.AppCompat.Light.NoActionBar" />
</resources>

values-v19/styles.xml
推荐使用(半透明化status bar和navigation bar)

<resources> 
  <style name="Theme.AppTheme.TranslucentStatusBar" parent="Theme.AppCompat.Light.NoActionBar"> 
    <item name = "android:windowTranslucentStatus">true</item>
    <item name = "android:windowTranslucentNavigation">true</item>
  </style>
</resources>

values-21/styles.xml
改变status bar颜色

<resources> 
  <style name="Theme.AppTheme.TranslucentStatusBar" parent="Theme.AppCompat.Light.NoActionBar"> 
    <item name="android:statusBarColor">@android:color/transparent</item>
  </style>
</resources>

values-23/styles.xml

<resources>
  <style name="Theme.AppTheme.TranslucentStatusBar" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:statusBarColor">@android:color/transparent</item>
    <item name="android:windowLightStatusBar">true</item>
  </style>
</resources>

具体使用

public class ImagePreActivity extends AppCompatActivity { 
 
  @Override 
  protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState);  
    if (Build.VERSION.SDK_INT  = Build.VERSION_CODES.LOLLIPOP) { 
      findViewById(android.R.id.content).setSystemUiVisibility( 
          View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE); 
    } 
    setContentView(R.layout.activity_image_pre_layout); 
  } 
} 
<activity 
  android:name=".ImagePreActivity" 
  android:theme="@style/Theme.AppTheme.TranslucentStatusBar" />

显示效果如下
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR`是一个View的系统UI标志,它可以用来改变Android设备的导航栏(虚拟按键栏)的颜色。 在Android 8.0及以上版本中,如果您想将虚拟按键栏的颜色更改为浅色(例如,从黑色变为白色),则可以使用该标志。 以下是如何使用`View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR`的步骤: 1. 在您的布局文件中,找到您想要更改虚拟按键栏颜色的视图(例如,一个Button或一个LinearLayout)。 2. 在Java代码中,获取该视图的引用,例如: ``` Button myButton = findViewById(R.id.my_button); ``` 3. 使用以下代码将`View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR`标志添加到该视图中: ``` if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { myButton.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR); } ``` 注意,由于该标志只适用于Android 8.0及更高版本,在设置该标志之前,您需要检查设备的Android版本是否符合要求。 4. 如果您想要在应用程序的整个界面中使用该标志,您可以将其添加到Activity中的根视图中,例如: ``` if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { View decorView = getWindow().getDecorView(); decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR); } ``` 这将在整个Activity中更改虚拟按键栏的颜色。 请注意,由于这个标志只适用于Android 8.0及以上版本,您需要在使用它之前检查设备的Android版本。另外,该标志只适用于具有虚拟按键的设备,例如Nexus和Pixel设备。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值