Android沉浸式状态栏(二)

来源:互联网 发布:淘宝uv价值 编辑:程序博客网 时间:2024/05/29 04:34

1.使用SystemBarTint实现沉浸式状态栏

关于Android沉浸式状态栏,很多人提到一个开源项目:SystemBarTint。

SystemBarTint提供了一个library,其实也就是一个类:SystemBarTintManager。通过引用该类,可以实现给4.4以上的状态栏指定颜色。

具体引用方法如下:

@Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_match_actionbar);        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {            setTranslucentStatus(true);        }        SystemBarTintManager tintManager = new SystemBarTintManager(this);        tintManager.setStatusBarTintEnabled(true);        tintManager.setStatusBarTintResource(R.color.statusbar_bg);    }    @TargetApi(19)     private void setTranslucentStatus(boolean on) {        Window win = getWindow();        WindowManager.LayoutParams winParams = win.getAttributes();        final int bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;        if (on) {            winParams.flags |= bits;        } else {            winParams.flags &= ~bits;        }        win.setAttributes(winParams);    }

同样应在布局文件里设置fitsSystemWindows属性:

这里写图片描述

是不是觉得引用方法有点复杂,经测试发现还可采用如下方法实现,不过两种方法有何不同还有待学习:

@Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_match_actionbar);        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {//          setTranslucentStatus(true);            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); // 状态栏        }        SystemBarTintManager tintManager = new SystemBarTintManager(this);        tintManager.setStatusBarTintEnabled(true);        tintManager.setStatusBarTintResource(R.color.statusbar_bg);    }//  @TargetApi(19) //  private void setTranslucentStatus(boolean on) {//      Window win = getWindow();//      WindowManager.LayoutParams winParams = win.getAttributes();//      final int bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;//      if (on) {//          winParams.flags |= bits;//      } else {//          winParams.flags &= ~bits;//      }//      win.setAttributes(winParams);//  }

2.学习SystemBarTint源码

与 Android沉浸式状态栏(一) 中提到的方法相比,使用SystemBarTint实现沉浸式状态栏添加了如下语句给状态栏指定颜色:

SystemBarTintManager tintManager = new SystemBarTintManager(this);tintManager.setStatusBarTintEnabled(true);tintManager.setStatusBarTintResource(R.color.statusbar_bg);

那么SystemBarTintManager是如何给状态栏指定颜色的呢?下面我们来学习SystemBarTintManager源码。
跟踪setStatusBarTintResource方法发现,该方法是给mStatusBarTintView设置背景颜色,可见mStatusBarTintView即为状态栏:

public void setStatusBarTintResource(int res) {        if (mStatusBarAvailable) {            mStatusBarTintView.setBackgroundResource(res);        }    }

在初始化SystemBarTintManager时,构造方法SystemBarTintManager(Activity activity)通过调用方法setupStatusBarView初始化mStatusBarTintView,并将其add到decorViewGroup中:

private void setupStatusBarView(Context context, ViewGroup decorViewGroup) {        mStatusBarTintView = new View(context);        LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, mConfig.getStatusBarHeight());        params.gravity = Gravity.TOP;        if (mNavBarAvailable && !mConfig.isNavigationAtBottom()) {            params.rightMargin = mConfig.getNavigationBarWidth();        }        mStatusBarTintView.setLayoutParams(params);        mStatusBarTintView.setBackgroundColor(DEFAULT_TINT_COLOR);        mStatusBarTintView.setVisibility(View.GONE);        decorViewGroup.addView(mStatusBarTintView);    }

可见只需要自定义一个View,把它放在状态栏的位置,就可以实现自定义状态栏。但是为什么DecorView可以更改状态栏?

DecorView为整个Window界面的最顶层View,它只有一个子元素为LinearLayout。代表整个Window界面,包含通知栏,标题栏,内容显示栏三块区域。
LinearLayout里有两个FrameLayout子元素。一个为标题栏显示界面,只有一个TextView显示应用的名称,也可以自定义标题栏,载入后的自定义标题栏View将加入FrameLayout中;另一个为内容栏显示界面,setContentView()方法载入的布局界面,就是加入其中。

这里写图片描述

关于DecorView有待深入了解,下面我根据SystemBarTint提供的方法,用一种比较轻量的方式简单的实现沉浸式状态栏。

3.通过DecorView实现沉浸式状态栏

private View mStatusBarTintView;    private ViewGroup decorViewGroup;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); // 状态栏        }        decorViewGroup = (ViewGroup) getWindow().getDecorView();        setupStatusBarView(this, decorViewGroup);    }    private void setupStatusBarView(Context context, ViewGroup decorViewGroup) {        mStatusBarTintView = new View(context);        LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, getStatusBarHeight(getResources()));        params.gravity = Gravity.TOP;        mStatusBarTintView.setLayoutParams(params);        mStatusBarTintView.setBackgroundColor(Color.BLUE);        decorViewGroup.addView(mStatusBarTintView);    }    private int getStatusBarHeight(Resources res) {        int result = 0;        int resourceId = res.getIdentifier("status_bar_height", "dimen", "android");        if (resourceId > 0) {            result = res.getDimensionPixelSize(resourceId);        }        return result;    }

和SystemBarTint实现方式相同,但不需要导入SystemBarTintManager类。其中Color.BLUE可以设置为想设置的任意颜色(设置为与ActionBar相同或相近的颜色即达到沉浸式状态栏效果)。

另:使用v7包中的android.support.v7.widget.Toolbar也可实现沉浸式状态栏,我将在下篇博客中学习。

0 0
原创粉丝点击