Android 沉浸式状态栏

关于沉浸式状态栏,网上挺多的,有一些还是第三方,个人感觉还是原生好一点,日常见到的比较多的情况就两种:

  1. toolbar + status 同色
  2. 一张图片延伸到状态栏。

第一种情况的效果图如下:

第二种情况的效果图如下:

*

步骤一

创建values-19文件夹和values-v21 (兼容)文件夹

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!--如果想代码设置背景色,设置成false-->
        <item name="android:windowTranslucentStatus">false</item>
        <!--是否拉起到扩展到状态栏 true  扩展到状态栏  false 不扩展到状态栏-->
        <item name="android:windowTranslucentNavigation">true</item>
        <!--Android5.X开始需要把颜色设置透明,否则导航栏会呈现系统默认的浅灰色-->
        <item name="android:statusBarColor">@android:color/transparent</item>
    </style>

    <style name="AppTheme.Main" parent="AppTheme" />
</resources>

windowTranslucentStatus设置成false,经过测试,个人理解是,去掉了status阴影部分(系统默认的灰色)。
windowTranslucentNavigation设置成true,这个我还没遇见过这个问题,网上说的是:是否拉起到扩展到状态栏 true 扩展到状态栏 false 不扩展到状态栏
statusBarColor就是设置status的颜色了,同理我们可以动态代码设置status的color。这里我们先设置成透明的transparent,以便于接下来的问题测试。

步骤二

分别由两种方法可以实现图一的效果

实现效果图1:

方法1:我们可以设置跟布局的fitsSystemWindows的属性为true,
官方解释:

android:fitsSystemWindows

Boolean internal attribute to adjust view layout based on
system windows such as the status bar. If true, adjusts the
padding of this view to leave space for the system windows.
Will only take effect if this view is in a non-embedded
activity.

设置为true,系统会自动计算出status的高度,会在屏幕最上方预留出paddingtop,其高度为status的高度。

此时我们的XML应该是这样的:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:fitsSystemWindows="true"
    tools:context="com.example.liumengqiang.designproject.MainActivity">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="@color/colorPrimary"
        app:contentInsetStart="0dp"/>

</LinearLayout>

效果图是这样的:

可以看到status顶部是白色透明的

此时可以通过style文件的statusBarColor属性或者代码修改,下面是代码修改的代码:

    /**
     * 5.0以上修改状态栏颜色
     */
    private void updateStatusColor() {
        Window window = this.getWindow();
        window.getDecorView().setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN| View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        window.setStatusBarColor(this.getResources().getColor(R.color.colorPrimary));
    }

效果图如下:

这种方法是有缺点的,当布局中有EditText时,会出现Toolbar整体上移的情况。

方法二:创建一个View代替顶部的status

首先我们创建一个view代替status,通过反射获取status的高度,将view高度动态设置为status的高度。

XML代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.liumengqiang.designproject.MainActivity">

    <View
        android:id="@+id/status_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="@color/colorPrimary"
        app:contentInsetStart="0dp"/>

</LinearLayout>

通过反射获取status的高度:

    /**
     * 利用反射获取状态栏高度
     * @return
     */
    private int getStatusBarHeight() {
        int result = 0;
        //获取状态栏高度的资源id
        int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            result = getResources().getDimensionPixelSize(resourceId);
        }
        return result;
    }

设置view的高度:

    private void initStatus() {
        View view = findViewById(R.id.status_view);
        ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
        layoutParams.height = getStatusBarHeight();
        view.setBackgroundColor(getResources().getColor(R.color.colorPrimary));
//        view.setBackgroundColor(Color.TRANSPARENT);
    }

效果图和上述一样;个人比较倾向第二种方法,能够避免很多小坑~;

实现效果图2:

首先我们将status的状态栏颜色设置成透明状态:

    private void initStatus() {
        View view = findViewById(R.id.status_view);
        ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
        layoutParams.height = getStatusBarHeight();
        view.setBackgroundColor(Color.TRANSPARENT);
    }

此时效果图和我们想要的效果是一样的,但是可以想象一下,我们layout的整体内容向上平移了status的高度,因为status透明隐藏了。实际我们想要的效果是layout内容的位置不变的,此时我们需要将上述方法二,创建一个view,然后把status的高度设置给view,最后将view的color设置为透明,这样就完美了~.

XMl代码如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.liumengqiang.designproject.MainActivity">

    <ImageView
        android:id="@+id/image"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scaleType="fitXY"
        android:src="@drawable/timg" />

    <View
        android:id="@+id/status_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</RelativeLayout>

简单对这两种情况做了封装,代码下载地址:

https://download.csdn.net/download/lmq121210/10503373

从年前拖更到现在….. six six six ~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值