首先说一下我对沉浸式状态栏的理解,在4.4之前,状态栏都是黑乎乎的,看起来很不美观,在4.4之后可以将状态栏设置成透明并和标题栏同一种颜色。以下是我总结的实现沉浸式的几种方式。

第一种方式:使用系统API实现沉浸式

1.1、首先看布局文件

添加android:fitsSystemWindows=”true”, android:clipToPadding=”true”两个属性

<?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"
    tools:context="teststatusbar.com.xn.teststatusbar.MainActivity">

    <TextView
        android:background="@android:color/holo_blue_dark"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:clipToPadding="true"
        android:fitsSystemWindows="true"
        android:onClick="firstWay"
        android:text="第一种方式实现沉浸式状态栏" />

</LinearLayout>

或者直接设置属性:

<item name="android:statusBarColor">@color/system_bottom_nav_color</item>,

这个属性是直接设置状态栏的颜色,这个属性是在style中设置的。或者直接用代码来改变颜色,只在5.0及以上才能起作用。

//5.0+可以直接用API来修改状态栏的颜色。    getWindow().setStatusBarColor(getResources().getColor(R.color.material_blue_grey_800));
<item name="android:windowTranslucentStatus">true</item>

这个属性就是设置状态栏为透明,同样在style文件中来设置的,但是有个弊端就是状态栏会往上移,所以标题栏的高度会减少,减少的高度为状态栏的高度,大概是24dp。这时我们通过反射机制来动态增加高度,或者给Toolbar设置android:fitsSystemWindows=”true”,或者给最外层的容器设置这个属性,这样也可以将减少的高度补回来。

1.2、java代码如下:
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initStatusbar();
    }

    /**
     * 初始化状态栏
     */
    private void initStatusbar() {
       //这里是判断当前的目标版本是否在4.4及以上,如果在4.4之上我们才设置沉浸式
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            //透明状态栏
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            //透明导航栏
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
        }
    }
}

效果如下:

cordova ios实现沉浸式状态栏 设置沉浸式状态栏_cordova ios实现沉浸式状态栏

第二种方式:使用反射机制动态加载标题栏

思路是这样的:先获取到状态栏的高度,再获取到我们自定义的标题栏的高度,然后将我们的标题栏的高度设置为两者之和,在这之前需要将我们原本的状态栏设为透明。这样就完成了我们的沉浸式状态栏。

2.1:在布局文件中定义好自定义的标题栏
<?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"
    tools:context="teststatusbar.com.xn.teststatusbar.SecondActivity">

    <LinearLayout
        android:id="@+id/line"
        android:layout_width="match_parent"
        android:layout_height="80dp"
        android:background="@android:color/holo_blue_dark">

        <TextView
            android:layout_gravity="center"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="第二种方式实现沉浸式状态栏" />
    </LinearLayout>
</LinearLayout>

高度我们设置的80dp。

2.2、在java代码中动态设置状态栏的高度
public class SecondActivity extends AppCompatActivity {
    LinearLayout lin;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        lin = (LinearLayout) findViewById(R.id.line);
        setStatus();
    }

    /**
     * 设置沉浸式状态栏
     */
    private void setStatus() {
        //判断是否是大于当前版本4.4,如果大于则实现沉浸式
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
//标题栏透明
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
//导航栏透明
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);

            lin.post(new Runnable() {
                @Override
                public void run() {
                    final int statusheight = getLayoutHeight();
                    final int linHeight = lin.getHeight();
                    Log.e("statusheight linHeight", ""+statusheight+":"+linHeight);
                    ViewGroup.LayoutParams layoutParams = lin.getLayoutParams();
                    layoutParams.height = statusheight + linHeight;
                    lin.setLayoutParams(layoutParams);
                }
            });
        }
    }

    /**
     * 获取状态栏的高度
     *
     * @return
     */
    public int getLayoutHeight() {
        try {
            Class<?> clazz = Class.forName("com.android.internal.R$dimen");
            Object obj = clazz.newInstance();
            Field field = clazz.getField("status_bar_height");
            int height = Integer.parseInt(field.get(obj).toString());
            return getResources().getDimensionPixelSize(height);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }
}

这里需要注意的是,获取我们自定义的状态栏的高度设置参数的代码,我们是放在view.post(new Runnable…)中的,为什么要放在这里面而不直接写呢,如果直接在onCreate方法里面获取一个view的参数如宽高等,是获取不到的,一直会是0,因为在onCreate方法中,也许view还没执行测量方法。

那为什么放在post方法中就能获取到了呢?这里是将Runnable添加到消息队列中,保证在UI线程中执行,这里就能保证在View绘制完成之后获取到宽高,就能取到值了。

最终的执行效果如下:

cordova ios实现沉浸式状态栏 设置沉浸式状态栏_material-design_02

第三种方式:使用Toolbar自动带有沉浸式的效果

Toolbar的具体使用方式详见:
其实本质就是5.0自动实现了沉浸式的效果,通过主题的设置来改变状态栏的颜色。colorPrimaryDark这个属性就是用来显示状态栏的颜色的。

<style name="AppTheme" parent="AppBaseTheme">
        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
        <item name="android:textColor">@color/mytextcolor</item>
        <item name="colorPrimary">@color/colorPrimary_pink</item>
        <item name="colorPrimaryDark">@color/colorPrimary_pinkDark</item>