美文网首页Android技术进阶-今晚吃啥子? -罗非鱼。UI
侧滑返回适配状态栏,避免内容布局与状态栏的“撕裂”效果

侧滑返回适配状态栏,避免内容布局与状态栏的“撕裂”效果

作者: 孔鹏飞 | 来源:发表于2021-05-20 18:11 被阅读0次

前言

所谓撕裂这里指的是侧滑返回上一级页面时,状态栏不随内容布局移动,造成状态栏和内容布局不联动,相分离的问题。

小红书APP设置页面 微信APP页面
xhs.gif wx.gif

问题分析

此处以小红书APP设置页面为例进行分析,通过uiautomatorviewer工具查看页面布局,布局结构如下:

小红书设置页面.png
  • 页面使用的是系统状态栏(idandroid: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

GitHub

https://github.com/kongpf8848/AndroidWorld

相关文章

网友评论

    本文标题:侧滑返回适配状态栏,避免内容布局与状态栏的“撕裂”效果

    本文链接:https://www.haomeiwen.com/subject/fxebjltx.html