Android 4.4 沉浸式状态栏的实现

Android 4.4(kitkat)之后,Android Window 提供一个新的属性:

WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
从名字上可以看出,这个属性可以用来设置状态栏是否透明,我们就可以利用这个属性来实现沉浸式的状态栏。沉浸式的实现跟布局有关,大致分为三种情况:

一、状态栏与页面大背景融合的沉浸式

Android 4.4 沉浸式状态栏的实现_第1张图片

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_first);
        setImmerseLayout();
    }
    protected void setImmerseLayout() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            Window window = getWindow();
            window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        }
    }
在Android 4.4 以上设置了FLAG_TRANSLUCENT_STATUS 属性,从图上看实际的效果就是界面背景填充了状态栏,这样就是实现了状态栏与页面大背景融合的沉浸式。

二、带有自定义ToolBar的沉浸式

带有自定义ToolBar的沉浸式根据布局是否有EditText分为两种情况:

1.没有EditText

Android 4.4 沉浸式状态栏的实现_第2张图片

先来看看xml布局文件




    

        

            
            

        
    
是不是觉得代码中ID为fl_toolbar的FrameLayout有点多余,恩,这是有用的。如果单单调用setImmerseLayout()方法,toolbar就会直接融合到状态栏上(跟第一种情况是一样的)。避免这种情况,我们可设置Pandding(内边距)来使状态栏和toolbar不重叠,FrameLayout在这里发挥作用了。代码如下:

    protected void setImmerseLayout(View view) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            Window window = getWindow();
            window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            int statusBarHeight = getStatusBarHeight(this.getBaseContext());
            view.setPadding(0, statusBarHeight, 0, 0);
        }
    }
这样就可以设置Pandding了,pandding的高度应该就是状态栏的高度了。国内的rom的状态栏高度没有统一的标准(MIUI高些,Flyme矮些),所以只能动态获取,就是getStatusBarHeight方法。

    /**
     * 用于获取状态栏的高度。 使用Resource对象获取
     *
     * @return 返回状态栏高度的像素值。
     */
    private 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;
    }

2.含有EditText

含有EditText的情况就比较特殊了,设置了状态栏透明属性,导致在软键盘弹出后页面没有resize,内容被键盘遮住,adjustResize或者ScrollView不起作用,这时候需要fitSystemWindows属性来解决问题。

fitSystemWindows属性

    官方描述:

        Boolean internal attribute to adjust view layout based on system windows such as the status bar. If true, adjusts the padding of this view to leave space for the system windows. Will only take effect if this view is in a non-embedded activity.

    简单描述:

     这个一个boolean值的内部属性,让view可以根据系统窗口(如status bar)来调整自己的布局,如果值为true,就会调整view的paingding属性来给system windows留出空间....

    实际效果:

     当status bar为透明或半透明时(4.4以上),系统会设置view的paddingTop值为一个适合的值(status bar的高度)让view的内容不被上拉到状态栏,当在不占据status bar的情况下(4.4以下)会设置paddingTop值为0(因为没有占据status bar所以不用留出空间)。

软键盘弹出后不遮挡内容,要求界面不能设置全屏,因此我们不能将fitSystemWindows属性设置在根layout,直接在需要relayout的子view上添加fitsSystemWindows属性即可。



        

            

                ...

                
            

        
    

效果图如下:

Android 4.4 沉浸式状态栏的实现_第3张图片

需要注意的一点是设置fitSystemWindows的view 的padding属性会失效。有暂时的解决方法是将fitSystemWindows属性设置在xml根layout,并且设置适当的背景颜色。例如:



    

以上就是Android 沉浸式的实际实现过程,另外需要注意的一点就是存在父Activity包含子Activity的情况的话(如:ActivityGroup),父Activity耶必须设置状态栏透明属性,即调用setImmerseLayout()方法,才能实现子Activity的沉浸式状态栏。

Demo下载http://download.csdn.net/detail/a496263987/9443821

你可能感兴趣的:(Android 4.4 沉浸式状态栏的实现)