Android4.4及以上关于状态栏的处理

关于状态栏沉浸式的处理,很多文章都详细讲到了。我看好多都在沉浸式这个叫法上纠缠不清,结果一张gif就说明了,WTF,这特么不就是全屏外带状态栏和导航栏自动延时隐藏么?索性我就不用这个高大上的词了,免得又把注意力引到这些个概念上(主要是小米没带好头。。。) 4.4以下(不包括4.4)最多做到隐藏状态栏,如果不隐藏,那就接受黑乎乎的一坨吧,变色?你想多了。

总结如下:

设计需求一:

半透明效果,activity内容占全屏(4.4和5.0及以上均保持半透明效果)

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

/*因为设置了状态栏半透明,所以activity内容将占据状态栏所在区域,很大可能会使得可视UI元素
*(比如textview所显示的文本或者一个顶部的搜索框)位于状态栏半透明背景下,需要在对应子节点中根据情况
*设置fitsSystemWindows="true",此属性设置在哪个view上,这个view就会将该view的paddingtop值设置为状态栏的高度,
*这时该view的原始paddingtop值将无效
*/

设计需求二:

4.4半透明,5.0及以上全透明(分为两种具体处理方式:1、5.0及以上内容占状态栏区域、2、5.0及以上内容不占状态栏区域)

方式一(占状态栏区域):

if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT){
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}else if(Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT){
    int flag = getWindow().getDecorView().getSystemUiVisibility();
    flag |= View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
    getWindow().getDecorView().setSystemUiVisibility(flag);
    getWindow().setStatusBarColor(Color.TRANSPARENT);
}

方式二(不占状态栏区域):

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

这种情况其实是不存在的,没有哪个设计师会要这种效果。为什么?既要状态栏透明,又不占用状态栏区域,这不就是在activity内容不占用状态栏区域的情况下,将activity的根布局背景颜色显示出来了么(根布局如果没有设置背景色,就会显示所应用主题的背景色)?这种效果给人视觉上的体验就是应用的背景占满了屏幕但是activity的内容UI元素没有铺满整个屏幕,很奇怪

设计需求三:

4.4、5.0及以上给状态栏着色(4.4和5.0以上分开讨论)

4.4上实际是无法给状态栏着色的,但是视觉上可以达到这个效果,那就是先半透明,然后下面的activity内容的颜色就自然而然可以显现出来。照上面"设计需求一"实现半透明后就显示了activity的界面内容颜色(要么纯色要么是非纯色,非纯色是指类似图片的显示)。非纯色显示不用做什么处理,对于纯色,在实现上也可以分为两种:1、类似非纯色的做法,不用作处理,直接显示;2、在顶部添加一个背景是纯色的view,高度等于状态栏高度。

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

    View statusBarTintView = new View(this);
    FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, getStatusBarHeight(this));
    params.gravity = Gravity.TOP;
    statusBarTintView.setLayoutParams(params);
    statusBarTintView.setBackgroundColor(getResources().getColor(R.color.colorPrimary));

    //这个做法有一点需要注意:添加到顶部的view(冒充状态栏背景)会盖住根布局的上面一条状态栏的区域,因此需要将根布局的paddingtop增加一个状态栏的高度,或者添加fitSystemWindow=true
    ((ViewGroup)getWindow().getDecorView()).addView(statusBarTintView);

    final View container = findViewById(R.id.container);
    container.setPadding(container.getPaddingLeft(), container.getPaddingTop() + getStatusBarHeight(this),container.getPaddingRight(), container.getPaddingBottom());
} else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {
}

/*
*获取状态栏高度
*/
public int getStatusBarHeight(Context context) {
    Context appContext = context.getApplicationContext();
    int result = 0;
    int resourceId =
        appContext.getResources().getIdentifier("status_bar_height", "dimen", "android");
    if (resourceId > 0) {
        result = appContext.getResources().getDimensionPixelSize(resourceId);
    }
    return result;
}

5.0及以上给状态栏着色比较简单,代码如下,这是实实在在地给状态栏着色。也可以像4.4上那样"视觉上"着色。两种方法,方法1跟上述4.4的做法一毛一样,属于半透明的做法;方法2则是全透明的做法,先按上面"设计需求二"全透明化,再按上述4.4的做法(去掉if判断后的第一行)。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    getWindow().setStatusBarColor(getResources().getColor(R.color.colorPrimary));
}

附布局代码,主题是Theme.AppCompat.Light.NoActionBar




    
        
    
    


到此4.4以上的关于状态栏沉浸式处理的情况都已囊括到,实际开发中根据需求选择合适的方式就ok了。有遗漏或者不对的,欢迎指正

你可能感兴趣的:(Android4.4及以上关于状态栏的处理)