沉浸式状态栏

1 首先要配置主题
  在value-21下建立自己项目中使用的主题 并添加如下属性
状态栏
<item name="android:windowTranslucentStatus">false</item>
虚拟按键是否透明,这个为truefitsSystemWindows属性才有效果
<item name="android:windowTranslucentNavigation">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>


2  关键属性 android:fitsSystemWindows="***"
这个属性当为true的时候代表子控件内容不会显示在状态栏上
当为false时子控件的内容允许显示在状态栏上,支持对布局里面多个子孩子添加


3 注意 这个属性只针对子孩子,并且需要自己处理状态栏的颜色,不然不太好看


4 发现的问题是,fragment创建后又销毁有创建 fitSystemWindows无效


侧拉布局沉濅式实现布局 参考
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <android.support.v4.widget.DrawerLayout
        android:id="@+id/drawer"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clickable="true">
        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            <!--填充状态栏 大概高度30dp 不需要那么准确,能填充状态栏-->
            <View
                android:layout_width="match_parent"
                android:layout_height="30dp"
                android:background="@color/colorPrimaryDark"></View>
<!--让子孩子显示在状态栏下面 并且设置虚拟按键背景颜色 ,设置虚拟按键背景颜色 主要是background -->
<LinearLayout                
android:layout_width="match_parent" 
android:layout_height="wrap_content" 
android:background="@drawable/lay_trans_color" 
android:fitsSystemWindows="true"                
android:orientation="vertical">               
<!--布局思路 上面为导航栏的颜色 下面为虚拟按键的颜色  中间为内容的颜色-->  
<!-- 由于上个布局设置了背景颜色为虚拟按键  子孩子不会显示在虚拟按键上 所以要恢复内容的背景颜色-->
<FrameLayout           
android:layout_width="match_parent"     
android:layout_height="0dp"          
android:layout_weight="1"
android:background="?android:windowBackground">
<!--在这里可以加入主体布局的内容 会正确的显示在屏幕内--> 
<TextView       
android:layout_width="wrap_content"     
android:layout_height="match_parent"
android:background="@color/red"
android:text="我是内容布局"  /> 
</FrameLayout>
</LinearLayout>
</FrameLayout>
<!--侧拉布局内容 下面配置的false 也就是子孩子允许显示在状态栏上--> 
<LinearLayout       
android:layout_width="wrap_content"     
android:layout_height="match_parent"    
android:layout_gravity="left"          
android:background="@color/white"   
android:clickable="true"          
android:fitsSystemWindows="false"
android:focusable="true"         
android:orientation="vertical"> 
<!--侧拉布局内容 在这里加入侧拉布局的xml  会显示在虚拟导航栏和状态栏上-->
<TextView       
android:layout_width="wrap_content"     
android:layout_height="match_parent" 
android:background="@color/yellow"
android:text="我是侧拉布局"  /> 

</LinearLayout>  
</android.support.v4.widget.DrawerLayout>
</android.support.design.widget.CoordinatorLayout>


lay_trans_color.xml 如下
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!--上面的30dp为透明颜色 下面的30dp设置为黑色 如果有虚拟按键显示为黑色-->
    <item android:top="30dp">
        <color android:color="@color/black"></color>
    </item>

</layer-list>


项目中具体效果如下




1 在fragment中发现当fragment销毁后有重新加载改fitsSystemWindows=true属性失效,可以通过一下方法解决。

在onActivityCreate里面调用此方法fixFitsSystemWindows即可

/**
 * fragment里面fitsSystemWindows=true有可能失效
 * </p>
 * 需要手动调用此方法,修复fitsSystemWindows属性失效问题
 * <p>
 * 带有fitSystemWindows=true属性的控件
 *
 * @param fixView
 */
public static void fixFitsSystemWindows(final View fixView) {
    //4.4低版本上面没有fitsSystem没有
    if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT)
        return;
    boolean fitsSystemWindows = fixView.getFitsSystemWindows();
    if (!fitsSystemWindows) return;
    //父控件 如果有这属性 fitsSystemWindows="true" 这个控件需要正确显示在屏幕内
    fixView.getViewTreeObserver().addOnGlobalLayoutListener(
            new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    fixView.getViewTreeObserver()
                            .removeGlobalOnLayoutListener(this);
                    //因为有了
                    int paddingTop = fixView.getPaddingTop();
                    if (paddingTop < 1)
                        paddingTop = ScreenUtils.getStatusHeight(fixView.getContext());
                    int navHeight = ScreenUtils.getNavigationBarHeight(fixView.getContext());
                    fixView.setPadding(0, paddingTop, 0, navHeight);
                }
            });
}


/**
 * 获得状态栏的高度
 *
 * @param context
 * @return
 */
public static int getStatusHeight(Context context) {

    int statusHeight = -1;
    try {
        Class<?> clazz = Class.forName("com.android.internal.R$dimen");
        Object object = clazz.newInstance();
        int height = Integer.parseInt(clazz.getField("status_bar_height")
                .get(object).toString());
        statusHeight = context.getResources().getDimensionPixelSize(height);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return statusHeight;
}


//获取虚拟按键的高度
public static int getNavigationBarHeight(Context context) {
    int result = 0;
    if (hasNavigationBar(context)) {
        Resources res = context.getResources();
        int resourceId = res.getIdentifier("navigation_bar_height", "dimen", "android");
        if (resourceId > 0) {
            result = res.getDimensionPixelSize(resourceId);
        }
    }
    return result;
}

public static boolean hasNavigationBar(Context activity) {

    Resources rs = activity.getResources();
    int id = rs.getIdentifier("config_showNavigationBar", "bool", "android");
    boolean hasNavBarFun=false;
    if (id > 0) {
        hasNavBarFun = rs.getBoolean(id);
    }
    try {
        Class systemPropertiesClass = Class.forName("android.os.SystemProperties");
        Method m = systemPropertiesClass.getMethod("get", String.class);
        String navBarOverride = (String)m.invoke(systemPropertiesClass, "qemu.hw.mainkeys");
        if ("1".equals(navBarOverride)) {
            hasNavBarFun = false;
        } else if ("0".equals(navBarOverride)) {
            hasNavBarFun = true;
        }
    } catch (Exception e) {
        hasNavBarFun = false;
    }
    return hasNavBarFun;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值