最近的项目中有用到设置状态栏透明,也就是做沉浸式状态栏,但是在实现的过程中也遇到了一些问题,所以在这里做个总结,同时寻求更好的解决方案。网上设置沉浸式状态栏的方式有好几种,以下是我采用的方法:
@TargetApi(19)
public void transparencyBar(Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = activity.getWindow();
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
| WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(Color.TRANSPARENT);
window.setNavigationBarColor(Color.TRANSPARENT);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
ViewGroup decorView = (ViewGroup)activity.getWindow().getDecorView();
decorView.removeViewAt(decorView.getChildCount() - 1);
ViewGroup rootView = (ViewGroup)((ViewGroup)activity.findViewById(android.R.id.content)).getChildAt(0);
rootView.setFitsSystemWindows(false);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
rootView.requestLayout();
}
AndroidBug5497Workaround.assistActivity(this);
}
同时要在布局文件里设置根布局android:fitsSystemWindows="false"。这种方式适合商城类详情页面,上面是图片,整个是一个scrollview。
第一个问题就是如果布局下方有edittext的话,当其获得焦点的时候,布局不会自动调整,有时会出现小键盘挡住edittext,用户体验不好。所以在上一段代码的最后引入了AndroidBug5497Workaround这个类。关于这个类的源码可查看:AndroidBug5497Workaround。引入后即可自动调整布局。注意:最后一句代码需与沉浸式状态栏一起设置,不可单独设置,否则自动调整的高度会有问题。
第二个问题是有的手机(例如华为)底部会有虚拟按键,上述的代码会使虚拟按键变成透明,并会挡住下面的布局。这个时候可以将window.setNavigationBarColor(Color.TRANSPARENT);这句代码注释掉,虚拟按键就不会变色了。关于虚拟按键挡住布局以及小键盘弹出时不调整布局其实都是因为android:fitsSystemWindows="false"引起的,但是改为true呢又会使顶部状态栏变回去。对于虚拟按键的问题,我选择了判断当前页面是否有虚拟按键,如果有点话就给被挡住的布局设置一个底部的padding,高度为虚拟按键的高度,没有虚拟按键的话就不处理。以下为我采用的判断是否有虚拟按键的代码:
/**
* 判断底部navigator是否已经显示
* @param windowManager 当前activity的windowManager(getWindowManager)
* @return 是否有虚拟按键
*/
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
public boolean hasSoftKeys(WindowManager windowManager){
Display d = windowManager.getDefaultDisplay();
DisplayMetrics realDisplayMetrics = new DisplayMetrics();
d.getRealMetrics(realDisplayMetrics);
int realHeight = realDisplayMetrics.heightPixels;
int realWidth = realDisplayMetrics.widthPixels;
DisplayMetrics displayMetrics = new DisplayMetrics();
d.getMetrics(displayMetrics);
int displayHeight = displayMetrics.heightPixels;
int displayWidth = displayMetrics.widthPixels;
bottomHeight = realHeight - displayHeight;
return (realWidth - displayWidth) > 0 || (realHeight - displayHeight) > 0;
}
其中bottomHeight就是虚拟按键的高度,可以存成常量并设置padding。这样设置之后就可以适配有虚拟按键的机型了。对于这些问题可能有更好的解决方案,我的方案也是从网上获取,希望能够帮到掉到坑里的同学。