问题描述
使用Fragment加底部导航是一个很常见的整体布局方案,既实用Activity承载一组Fragment来做内容分类导航。为了实现沉浸式体验,不同的Fragment需要有不同的状态栏来配合。
通常设置Activity的fitsSystemWindows为true来实现沉浸式体验,但是对于不同的Fragment又无能为力。
android:fitsSystemWindows="true"
解决方案
在Activity的onCreate里设置状态栏为透明。
@TargetApi(19)
public static 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) {
Window window = activity.getWindow();
window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
}
然后在不同的Fragment里边用不同的View来填充透明状态栏来获得不同的沉浸式效果。
在Fragment的布局里第一个元素位置放置占位View。
<View
android:id="@+id/status_bar_fix"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="@color/white" />
然后在Fragment的onCreateView里填充不同的效果
View mStateBarFixer = view.findViewById(R.id.status_bar_fix);
mStateBarFixer.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
getStatusBarHeight(getActivity())));
mStateBarFixer.setBackgroundColor(getResources().getColor(R.color.white));
public static int getStatusBarHeight(Activity a) {
int result = 0;
int resourceId = a.getResources().getIdentifier("status_bar_height",
"dimen", "android");
if (resourceId > 0) {
result = a.getResources().getDimensionPixelSize(resourceId);
}
return result;
}
带来的新问题
在华为等有虚拟按键的手机上,Activity的Layout会被虚拟键盘遮挡。
借图一张:
1.jpg
对于有虚拟按键的手机,要避免虚拟按键遮挡布局的问题,需要设置
android:fitsSystemWindows="true"
因此上面的方案就不可行了。