Android技术进阶-今晚吃啥子? -罗非鱼。UI

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

2021-05-20  本文已影响0人  孔鹏飞

前言

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

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

问题分析

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

小红书设置页面.png

解决办法

要想使侧滑时状态栏和内容布局一起滑动,一般的解决办法如下:

代码实现

此处假设使用的侧滑控件为SwipeBackLayout,此控件是在onPostCreate方法里添加侧滑布局,因此我们覆盖onPostCreate方法,在此方法里适配状态栏即可。


    /**
     * 获取自定义的状态栏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
    }

    @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

上一篇 下一篇

猜你喜欢

热点阅读