前言
所谓撕裂这里指的是侧滑返回上一级页面时,状态栏不随内容布局移动,造成状态栏和内容布局不联动,相分离的问题。
小红书APP设置页面 | 微信APP页面 |
---|---|
xhs.gif | wx.gif |
问题分析
此处以小红书APP设置页面为例进行分析,通过uiautomatorviewer
工具查看页面布局,布局结构如下:
- 页面使用的是系统状态栏(
id
为android:id/statusBarBackground
),状态栏背景颜色为白色。 - 侧滑布局不包含系统状态栏,侧滑返回时,内容布局在滑动,系统状态栏固定不动。
解决办法
要想使侧滑时状态栏和内容布局一起滑动,一般的解决办法如下:
- 设置系统状态栏背景颜色为透明。
- 页面布局延伸到状态栏区域,由页面负责状态栏的绘制,侧滑布局包含该状态栏区域。
- 自定义View填充状态栏区域或设置页面的顶部布局如TitleBar的topPadding为状态栏高度。
代码实现
此处假设使用的侧滑控件为SwipeBackLayout,此控件是在onPostCreate
方法里添加侧滑布局,因此我们覆盖onPostCreate
方法,在此方法里适配状态栏即可。
- 基类
BaseActivity
继承SwipeBackActivity
,定义一些状态栏和导航栏相关的方法。
/**
* 获取自定义的状态栏View,如为null,则采用默认的View填充状态栏区域
*/
protected open fun getStatusBarView(): View? {
return null
}
/**
* 状态栏颜色
*/
protected open fun statusBarColor(): Int {
return R.color.white
}
/**
* 导航栏颜色
*/
protected open fun navigationBarColor(): Int {
return R.color.white
}
/**
* 状态栏字体颜色是否高亮
*/
protected open fun statusBarDarkFont(): Boolean {
return true
}
/**
* 导航栏字体颜色是否高亮
*/
protected open fun navigationBarDarkFont(): Boolean {
return true
}
- 覆盖
onPostCreate
方法,设置状态栏和导航栏背景和字体颜色。
@Override
override fun onPostCreate(savedInstanceState: Bundle?) {
super.onPostCreate(savedInstanceState)
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
/**
* 设置系统状态栏背景颜色为透明
*/
window.statusBarColor = Color.TRANSPARENT
var uiFlags = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
/**
* 高亮状态栏字体
*/
if(statusBarDarkFont()) {
uiFlags = uiFlags or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
}
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
/**
* 高亮导航栏字体
*/
if(navigationBarDarkFont()) {
uiFlags = uiFlags or View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
}
}
window.decorView.systemUiVisibility = uiFlags
/**
* 获取状态栏高度
*/
val statusBarHeight = ScreenHelper.getStatusbarHeight(this)
/**
* 获取状态栏View
*/
var statusBarView=getStatusBarView()
if(statusBarView==null) {
statusBarView = View(this)
statusBarView.id = R.id.status_bar_id
val contentView = window.decorView.findViewById(android.R.id.content) as ViewGroup
/**
* 设置Padding
*/
contentView.getChildAt(0).setPadding(0, statusBarHeight, 0, 0)
/**
* 添加状态栏布局
*/
contentView.addView(statusBarView, ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, statusBarHeight))
}
else{
setStatusBarHeight(statusBarView)
}
statusBarView.setBackgroundColor(ContextCompat.getColor(applicationContext,statusBarColor()))
window.navigationBarColor = ContextCompat.getColor(applicationContext,navigationBarColor())
}
/**
* 设置View高度为状态栏高度
*/
fun setStatusBarHeight(view:View?) {
if(view==null){
return
}
val fixHeight=ScreenHelper.getStatusbarHeight(this)
var layoutParams = view.layoutParams
if (layoutParams == null) {
layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
}
if (layoutParams.height == ViewGroup.LayoutParams.WRAP_CONTENT || layoutParams.height == ViewGroup.LayoutParams.MATCH_PARENT) {
val finalLayoutParams = layoutParams
view.post(Runnable {
finalLayoutParams.height = fixHeight
view.layoutParams = finalLayoutParams
})
} else {
layoutParams.height = fixHeight
view.layoutParams = layoutParams
}
}
实现效果
1 | 2 |
---|---|
1.gif | 2.gif |
网友评论