android沉浸式状态栏的实现

在android4,4之后可以通过修改状态栏和导航栏实现沉浸式状态栏,在5.0之后增加了其他一些支持。主要通过getWindow().addFlags和getDecorView().setSystemUiVisibility实现相关的设置。

(1)通过getWindow().addFlags设置状态栏

   

if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        }

 通过FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS使根布局可以使用状态栏。


<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    xmlns:android="http://schemas.android.com/apk/res/android">
    
    <TextView
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:fitsSystemWindows="true"
        android:background="@color/colorPrimary"
        android:gravity="center_horizontal"
        android:textColor="@android:color/white"
        android:textSize="20sp"
        android:text="测试"
        />

</LinearLayout>

android:fitsSystemWindows="true"的作用使View忽略掉设置的padding,增加一个与状态栏等高的paddingfTop()(只有状态栏透明才有效),这样透明的状态栏会根据头部View的颜色显示自身的颜色,并会一层阴影。但4.4的阴影的效果是渐变,而5.0之后是一层较深的阴影的,为了使两个版本的效果相同。可以在根布局增加一层与状态栏等高的View,并设置其颜色。5.0之后可以单独设置状态栏颜色:getWindow().setStatusBarColor(getResources().getColor(R.color.colorPrimary));所以在4.4系统通过添加头部的View设置状态栏颜色,5.0以上通过setStatusBarColor设置状态栏颜色。

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_getwindow);
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
            getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
                getWindow().setStatusBarColor(getResources().getColor(R.color.colorPrimary));
            }else {
                addTopView(getResources().getColor(R.color.colorPrimary));
            }
        }
    }

    private void addTopView(int color){
        ViewGroup contentView = (ViewGroup) findViewById(android.R.id.content);
        View view = new View(this);
        ViewGroup.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,getStatusBarHeight());
        view.setLayoutParams(params);
        view.setBackgroundColor(color);
        contentView.addView(view);
    }

    //获取状态栏高度
    private int getStatusBarHeight(){
        int height = 0;
        int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            //根据资源ID获取响应的尺寸值
            height = getResources().getDimensionPixelSize(resourceId);
        }
        return height;
    }

(2)通过getDecorView().setSystemUiVisibility设置状态栏颜色

setSystemUiVisibility中的参数:

View.SYSTEM_UI_FLAG_VISIBLE API 14   默认标记

View.SYSTEM_UI_FLAG_LOW_PROFILE API 14  低调模式, 会隐藏不重要的状态栏图标

View.SYSTEM_UI_FLAG_LAYOUT_STABLE API 16  保持整个View稳定, 常和控制System UI悬浮, 隐藏的Flags共用, 使View不会因为System UI的变化而重新layout

View.SYSTEM_UI_FLAG_FULLSCREEN API 16     状态栏隐藏,效果同设置WindowManager.LayoutParams.FLAG_FULLSCREEN

View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN API 16    视图延伸至状态栏区域,状态栏上浮于视图之上

View.SYSTEM_UI_FLAG_HIDE_NAVIGATION API 14     隐藏导航栏

View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION API 16   视图延伸至导航栏区域,导航栏上浮于视图之上

View.SYSTEM_UI_FLAG_IMMERSIVE API 19
沉浸模式, 隐藏状态栏和导航栏, 并且在第一次会弹泡提醒, 并且在状态栏区域滑动可以呼出状态栏(这样会系统会清楚之前设置的View.SYSTEM_UI_FLAG_FULLSCREEN或View.SYSTEM_UI_FLAG_HIDE_NAVIGATION标志)。使之生效,需要和View.SYSTEM_UI_FLAG_FULLSCREEN,View.SYSTEM_UI_FLAG_HIDE_NAVIGATION中的一个或两个同时设置。

View.SYSTEM_UI_FLAG_IMMERSIVE_STIKY API 19
与上面唯一的区别是, 呼出隐藏的状态栏后不会清除之前设置的View.SYSTEM_UI_FLAG_FULLSCREEN或View.SYSTEM_UI_FLAG_HIDE_NAVIGATION标志,在一段时间后将再次隐藏系统栏)


 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_setsysui);
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
            getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN );
            getWindow().setStatusBarColor(Color.TRANSPARENT);
        }
    }


SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN的作用使视图衍生至状态栏,状态栏悬浮在视图上,会有一层阴影,所以设置状态栏明。SYSTEM_UI_FLAG_LAYOUT_STABLE

使View不会随UI的变化重新layout,一般与System UI的悬浮和隐藏一起使用。


(3)设置真正的沉浸式状态栏

为什么叫真正的沉浸式状态栏,因为上面的效果只是改变了状态了的颜色,沉浸式状态栏应该像爱奇艺一样播放电影时,隐藏掉状态栏和导航栏,



@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_immersive);
        getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
                View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
                View.SYSTEM_UI_FLAG_FULLSCREEN |
                View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
                View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
                View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY );
    }


SYSTEM_UI_FLAG_IMMERSIVE 和 SYSTEM_UI_FLAG_IMMERSIVE_STIKY都是设置沉浸式模式,一般与SYSTEM_UI_FLAG_FULLSCREEN或SYSTEM_UI_FLAG_HIDE_NAVIGATION一起使用,当手指在屏幕边缘往内滑时,会显示状态栏和导航栏。但SYSTEM_UI_FLAG_IMMERSIVE显示了状态栏或导航栏后会清楚设置的(SYSTEM_UI_FLAG_FULLSCREEN或SYSTEM_UI_FLAG_HIDE_NAVIGATION),所以就会显示状态栏和导航栏。而SYSTEM_UI_FLAG_IMMERSIVE_STIKY不会清楚掉之前的设置,显示的状态栏或导航栏过几秒会自动隐藏。SYSTEM_UI_FLAG_IMMERSIVE时可以通过getWindow().setStatusBarColor(color)和getWindow().setNavigationBarColor(color)设置状态栏和导航栏的颜色。SYSTEM_UI_FLAG_IMMERSIVE_STIKY时,状态栏和导航栏的颜色默认半透明

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值