viewpager+fragment实现沉浸式状态栏

本文介绍如何在MainActivity中使用ViewPager+Fragment的方式实现不同Fragment状态栏颜色的设置,并适配刘海屏和水滴屏设备。通过代码示例展示了如何获取状态栏高度、设置状态栏颜色及字体颜色,以及针对特定ROM(如MIUI、Flyme)进行的额外适配。
摘要由CSDN通过智能技术生成

MainActivity中使用ViewPager+Fragment的方式作为首页,但是每个fragment有独立的状态栏颜色,同时还要适配刘海屏,水滴屏。

直接上代码:

<!--给APP设置为无标题栏样式,在style下-->

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

如图:

状态栏是一个view,那我们就在代码中设置状态栏的高度

<!--给Fragment的加一个View作为状态栏-->

 <View
    android:id="@+id/view_status"
    android:layout_width="match_parent"
    android:layout_height="5dp"/>

问题来了,刘海屏,水滴屏这么做会存在UI显示问题的,所以就我们只有获取刘海屏,水滴屏状态栏的高度然后给View设置了。

/**
* 获取状态栏高度
*
* @param context
* @return
*/
public 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;
}

/**
* 设置状态栏高度,颜色
*
* @param view   要设置的状态栏的view
* @param color  要设置的颜色
* @return
*/
public void statusBarClor(View view, int color) {
    LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(getActivity()));
    view.setLayoutParams(lp);
    view.setBackgroundColor(getResources().getColor(color));
    
    if (Build.VERSION.SDK_INT >= 21) {
        View decorView = getActivity().getWindow().getDecorView();
        int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
        decorView.setSystemUiVisibility(option);
        getActivity().getWindow().setStatusBarColor(Color.TRANSPARENT);
    }
}

SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN:使状态栏出现的时候,不会重新调整activity的高度,状态栏覆盖在activity之上。
SYSTEM_UI_FLAG_LAYOUT_STABLE:让应用的主体内容占用系统状态栏的空间;
setStatusBarColor:使状态栏透明

上面的内容都是一些配置,把statusBarClor()这个方法加入到fragment中即可实现沉浸式状态栏,如图所示:

从图片中看到一个状态栏的字体都没有了,这是因为状态栏字体原本为白色,状态栏背景颜色也设置为了白色,造成重叠,因此接下来改造状态栏字体颜色。

/**
* 设置6.0状态栏深色浅色切换
* @param activity  activity
* @param dark      是否是浅色状态栏  true为浅色
* @return
*/
public static boolean setCommonUI(Activity activity, boolean dark) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        View decorView = activity.getWindow().getDecorView();
        if (decorView != null) {
            int vis = decorView.getSystemUiVisibility();
            if (dark) {
                vis |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
            } else {
                vis &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
            }
            if (decorView.getSystemUiVisibility() != vis) {
                decorView.setSystemUiVisibility(vis);
            }
            return true;
        }
    }
    return false;
}
将此方法加入进去即可。

 最终效果图

小米,魅族需要单独做适配,代码如下,判断ROM后加入即可

/**
* 设置MIUI状态栏深色浅色切换
*
* @param activity
* @param dark
* @return
*/
public static boolean setMiuiUI(Activity activity, boolean dark) {
    try {
        Window window = activity.getWindow();
        Class<?> clazz = activity.getWindow().getClass();
        @SuppressLint("PrivateApi") Class<?> layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams");
        Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE");
        int darkModeFlag = field.getInt(layoutParams);
        Method extraFlagField = clazz.getDeclaredMethod("setExtraFlags", int.class, int.class);
        extraFlagField.setAccessible(true);
        if (dark) {    //状态栏亮色且黑色字体
            extraFlagField.invoke(window, darkModeFlag, darkModeFlag);
        } else {
            extraFlagField.invoke(window, 0, darkModeFlag);
        }
        return true;
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }
}

/**
* 设置Flyme状态栏深色浅色切换
*
* @param activity
* @param dark
* @return
*/
public static boolean setFlymeUI(Activity activity, boolean dark) {
    try {
        Window window = activity.getWindow();
        WindowManager.LayoutParams lp = window.getAttributes();
        Field darkFlag = WindowManager.LayoutParams.class.getDeclaredField("MEIZU_FLAG_DARK_STATUS_BAR_ICON");
        Field meizuFlags = WindowManager.LayoutParams.class.getDeclaredField("meizuFlags");
        darkFlag.setAccessible(true);
        meizuFlags.setAccessible(true);
        int bit = darkFlag.getInt(null);
        int value = meizuFlags.getInt(lp);
        if (dark) {
            value |= bit;
        } else {
            value &= ~bit;
        }
        meizuFlags.setInt(lp, value);
        window.setAttributes(lp);
        return true;
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值