Android实现activity内嵌fragment时状态栏浸入式

时间:2024-05-21 11:35:14

1.概述

开发遇到浸入式  有时候也挺头疼的  新公司开发又遇到浸入式的问题了  于是研究了一下  完成了需求  记录一下

浸入式其实就是状态栏半透明的效果 能够在页面滑动的时候状态栏背景和页面的背景一致

2.效果图

这里就是浸入式的效果了  值得一提的是  浸入式的透明效果在 华为等部分手机上不是全透明的  

就像下面 有个明显的半透明色值

Android实现activity内嵌fragment时状态栏浸入式Android实现activity内嵌fragment时状态栏浸入式

3.实现浸入式

首先先看我给的样式

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
    <item name="android:listDivider">@drawable/recycler_head_grad_item</item>
</style>

样式的作用是让我们的activity充满整个屏幕 包括状态栏 

布局文件如下  id为header的linearLayout即我们activity的title

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/white"
    android:orientation="vertical">

    <LinearLayout
        android:id="@+id/header"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="@color/bluecolor"
        android:gravity="center"
        android:orientation="horizontal">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="消息"
            android:textColor="@color/white"
            android:textSize="18sp" />

    </LinearLayout>

 此时的效果是这个样子的

Android实现activity内嵌fragment时状态栏浸入式

可以发现 此时状态栏并没有自己的高度  我们的title顶到最上面去了  这样的话我们的标题会被状态栏覆盖达不到我们想要的效果   

我的想法是给title一个更高的高度  然后让我们的title  padding顶部一个状态栏的高度   然后内容居中这样就达到我们想要的效果了 代码如下

private void initView(View view) {
    View view1 = view.findViewById(R.id.header);
    initAfterSetContentView(getActivity(), view1);


@TargetApi(Build.VERSION_CODES.KITKAT)
public static void initAfterSetContentView(Activity activity, View titleViewGroup) {
    if (activity == null)
        return;
    if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {
        Window window = activity.getWindow();
        window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        if (titleViewGroup == null)
            return;
        // 设置头部控件ViewGroupPaddingTop,防止界面与状态栏重叠
        int statusBarHeight = getStatusBarHeight(activity);
        titleViewGroup.setPadding(0, statusBarHeight, 0, 0);
    }
}
/**
 * 获取状态栏高度
 * @param context
 * @return
 */
private static int getStatusBarHeight(Context context) {
    int result = 0;
    int resourceId = context.getResources().getIdentifier(
            "status_bar_height", "dimen", "android");
    if (resourceId > 0) {
        result = context.getResources().getDimensionPixelSize(resourceId);
    }
    return result;
}

这样做的目的就是让我们的title距离顶部一个状态栏的高度 这样效果就达到了我们效果图的样子  

这样可以解决一个activity内嵌多个fragment时的浸入式

因为之前我的想法是在每一个fragment中设置状态栏   前三个状态栏设置状态栏颜色  第四个设置浸入式 

但我发现 这样是有bug的 因为我在前三个fragment中给状态栏设置颜色  在第四个fragment是让状态栏浸入式  

当我点到第四个fragment时  整个activity都变成浸入式了  

我意识到我犯了一个错误fragment中改变的也是activity的状态栏 于是我改成上面代码的模式了 

当然不要忘记在你的mainActivity中添加上状态栏半透明的代码

// 状态栏透明
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}


如有错误敬请指正 不胜感激


后来发现一个bug及时更正  在安卓版本5.0一下的手机是没有浸入式的  我这样做就会导致状态栏高度特别高  我手动修改了一下高度  代码如下

@TargetApi(Build.VERSION_CODES.KITKAT)
public static void initAfterSetContentView(Activity activity,
                                           View titleViewGroup) {
    if (activity == null){
        return;
    }

    if (titleViewGroup == null){
        return;
    }

    if (Build.VERSION.SDK_INT >Build.VERSION_CODES.KITKAT) {
        Window window = activity.getWindow();
        window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        // 设置头部控件ViewGroupPaddingTop,防止界面与状态栏重叠
        int statusBarHeight = getStatusBarHeight(activity);
        titleViewGroup.setPadding(0, statusBarHeight, 0, 0);
    }else {
        LinearLayout.LayoutParams params= (LinearLayout.LayoutParams) titleViewGroup.getLayoutParams();
        params.height = 70;
        titleViewGroup.setLayoutParams(params);
    }
}