关于使用BGASwipeBackLayout-Android结合StatusBarUtil的问题
背景
【关于使用BGASwipeBackLayout-Android结合StatusBarUtil的问题】在写Reading的过程中,想实现仿IOS右滑关闭Activity的效果,在网上找到了BGASwipeBackLayout-Android
,看着效果不错,刚巧这个库也使用的猴子的StatusBarUtil
,在使用的过程中,效果确实不错,同时这个库也支持了右滑关闭Activity时候沉浸式通知栏,但是Reading里面用到了DrawerLayout,结合BGASwipeBackLayout-Android使用的时候出现了下面的问题,就是当从主Activity进入二层界面再返回的时候,底部Tab会弹一下再上来,效果有些炸眼....
文章图片
2018-08-25 00_05_55.gif
解决
想要解决这个问题无非从两个角度去思考
- BGASwipeBackLayout-Android
- StatusBarUtil
/**
* 为滑动返回界面设置状态栏颜色
*
* @param activity 需要设置的activity
* @param color状态栏颜色值
*/
public static void setColorForSwipeBack(Activity activity, int color) {
setColorForSwipeBack(activity, color, DEFAULT_STATUS_BAR_ALPHA);
}
/**
* 为滑动返回界面设置状态栏颜色
*
* @param activity需要设置的activity
* @param color状态栏颜色值
* @param statusBarAlpha 状态栏透明度
*/
public static void setColorForSwipeBack(Activity activity, @ColorInt int color,
@IntRange(from = 0, to = 255) int statusBarAlpha) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {ViewGroup contentView = ((ViewGroup) activity.findViewById(android.R.id.content));
View rootView = contentView.getChildAt(0);
int statusBarHeight = getStatusBarHeight(activity);
if (rootView != null && rootView instanceof CoordinatorLayout) {
final CoordinatorLayout coordinatorLayout = (CoordinatorLayout) rootView;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
coordinatorLayout.setFitsSystemWindows(false);
contentView.setBackgroundColor(calculateStatusColor(color, statusBarAlpha));
boolean isNeedRequestLayout = contentView.getPaddingTop() < statusBarHeight;
if (isNeedRequestLayout) {
contentView.setPadding(0, statusBarHeight, 0, 0);
coordinatorLayout.post(new Runnable() {
@Override
public void run() {
coordinatorLayout.requestLayout();
}
});
}
} else {
coordinatorLayout.setStatusBarBackgroundColor(calculateStatusColor(color, statusBarAlpha));
}
} else {
contentView.setPadding(0, statusBarHeight, 0, 0);
contentView.setBackgroundColor(calculateStatusColor(color, statusBarAlpha));
}
setTransparentForWindow(activity);
}
}
这段代码我们可以看到通过获取根布局,如果跟布局是CoordinatorLayout的话,设置paddingTop,并且设置颜色重绘。否则给contentView设置了paddingTop并且设置颜色。参考这段代码,我们找到了猴子的为DrawerLayout提供的沉浸式代码
/**
* 为DrawerLayout 布局设置状态栏变色
*
* @param activity需要设置的activity
* @param drawerLayoutDrawerLayout
* @param color状态栏颜色值
* @param statusBarAlpha 状态栏透明度
*/
public static void setColorForDrawerLayout(Activity activity, DrawerLayout drawerLayout, @ColorInt int color,
@IntRange(from = 0, to = 255) int statusBarAlpha) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
return;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
} else {
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
// 生成一个状态栏大小的矩形
// 添加 statusBarView 到布局中
ViewGroup contentLayout = (ViewGroup) drawerLayout.getChildAt(0);
View fakeStatusBarView = contentLayout.findViewById(FAKE_STATUS_BAR_VIEW_ID);
if (fakeStatusBarView != null) {
if (fakeStatusBarView.getVisibility() == View.GONE) {
fakeStatusBarView.setVisibility(View.VISIBLE);
}
fakeStatusBarView.setBackgroundColor(color);
} else {
contentLayout.addView(createStatusBarView(activity, color), 0);
}
// 内容布局不是 LinearLayout 时,设置padding top
if (!(contentLayout instanceof LinearLayout) && contentLayout.getChildAt(1) != null) {
contentLayout.getChildAt(1)
.setPadding(contentLayout.getPaddingLeft(), getStatusBarHeight(activity) + contentLayout.getPaddingTop(),
contentLayout.getPaddingRight(), contentLayout.getPaddingBottom());
}
// 设置属性
setDrawerLayoutProperty(drawerLayout, contentLayout);
addTranslucentView(activity, statusBarAlpha);
}
从代码来看,一眼看到代码注释//生成一个状态栏大小的矩形,也就是说支持DrawerLayout沉浸的原理是为跟布局设置 android:fitsSystemWindows="true",让整个屏幕都可以放组件,同时加了一个状态栏大小的矩形,并设置了颜色,这样就满足了DrawerLayout的沉浸式。
- 1.fitsSystemWindow 默认是true,就是组件都在屏幕内,但是不包括statusBar。设置成false后,整个屏幕都可以放置组件,没有statusBar和window之分。
- 2.android:fitsSystemWindows=“true”在布局中占有最高权限,如果明确设置为true,style设置fits为false是无效的;同理,只在布局中设置fits而没有设置style也是无效的。
/**
* 为滑动返回界面设置状态栏颜色
*
* @param activity需要设置的activity
* @param color状态栏颜色值
* @param statusBarAlpha 状态栏透明度
*/
public static void setColorForSwipeBackDrawerLayout(Activity activity, @ColorInt int color,
@IntRange(from = 0, to = 255) int statusBarAlpha) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {ViewGroup contentView = ((ViewGroup) activity.findViewById(android.R.id.content));
View rootView = contentView.getChildAt(0);
int statusBarHeight = getStatusBarHeight(activity);
if (rootView != null && rootView instanceof CoordinatorLayout) {
final CoordinatorLayout coordinatorLayout = (CoordinatorLayout) rootView;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
coordinatorLayout.setFitsSystemWindows(false);
contentView.setBackgroundColor(calculateStatusColor(color, statusBarAlpha));
boolean isNeedRequestLayout = contentView.getPaddingTop() < statusBarHeight;
if (isNeedRequestLayout) {
contentView.setPadding(0, statusBarHeight, 0, 0);
coordinatorLayout.post(new Runnable() {
@Override
public void run() {
coordinatorLayout.requestLayout();
}
});
}
} else {
coordinatorLayout.setStatusBarBackgroundColor(calculateStatusColor(color, statusBarAlpha));
}
}
setTransparentForWindow(activity);
}
}
为主Activity设置setColorForSwipeBackDrawerLayout方法,只需要把setPaddingTop删除掉就可以了,运行看效果我们发现从二级滑动返回到主Activity后底部Tab不会再上移,但是DrawerLayout不支持沉浸了,所以我们再调用一下猴子的代码 就解决了该问题。
/**
* 为DrawerLayout 布局设置状态栏颜色,纯色
*
* @param activity需要设置的activity
* @param drawerLayout DrawerLayout
* @param color状态栏颜色值
*/
public static void setColorNoTranslucentForDrawerLayout(Activity activity, DrawerLayout drawerLayout, @ColorInt int color) {
setColorForDrawerLayout(activity, drawerLayout, color, 0);
}
最后感谢两位大佬的开源...王浩
BGASwipeBackLayout-Android
猴子
StatusBarUtil
推荐阅读
- 由浅入深理解AOP
- 【译】20个更有效地使用谷歌搜索的技巧
- 关于QueryWrapper|关于QueryWrapper,实现MybatisPlus多表关联查询方式
- mybatisplus如何在xml的连表查询中使用queryWrapper
- MybatisPlus|MybatisPlus LambdaQueryWrapper使用int默认值的坑及解决
- MybatisPlus使用queryWrapper如何实现复杂查询
- 四首关于旅行记忆的外文歌曲
- 醒不来的梦
- iOS中的Block
- Linux下面如何查看tomcat已经使用多少线程