安卓

Activity中多个Fragment的fitsSystemWi

2020-03-27  本文已影响0人  远在远方的风yzyfdf

先看布局

Fragment添加到FrameLayout中,当fragment切换时,只有第一个fragment的fitsSystemWindows起作用了

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".ui.MainActivity">

    <FrameLayout
        android:id="@+id/main_container"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="horizontal" />
    
    <com.flyco.tablayout.CommonTabLayout
        android:id="@+id/tabLayout"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_gravity="bottom"
        android:background="@color/bg_light"
        android:elevation="3dp"
        app:tl_iconHeight="@dimen/dp24"
        app:tl_iconWidth="@dimen/dp24"
        app:tl_indicator_height="0dp"
        app:tl_textSelectColor="@color/main_color"
        app:tl_textUnselectColor="@color/text3"
        app:tl_textsize="0sp"
        app:tl_underline_height="0dp">

    </com.flyco.tablayout.CommonTabLayout>

</LinearLayout>

原因和解决方法

当第一个Fragment添加到Activity中的时候,Activity寻找出有fitsSystemWindows的子布局为其预留出状态栏的空间,其实就是设置一个padding,而其他Fragment添加到Activity中的时候,因为状态栏空间的适配已经被消费过一次了,Activity并不会再次去添加这个padding。因此我们需要自定义一个FrameLayout,重写它的状态栏空间适配的时机和它的适配事件的分发。因为Fragment是添加到FrameLayout这个容器的,给他设置一个布局层次结构改变的监听,当Fragment被添加进去的时候,通过requestApplyInsets()方法使Activity重新进行一次状态栏空间的适配,因为FrameLayout中还有其他的Fragment,我们还需要重写onApplyWindowInsets()方法,对其子View进行遍历,逐个分发状态栏空间的适配事件。

class WindowInsetsFrameLayout @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr) {

    init {
        //当层次结构发生改变时回调
        setOnHierarchyChangeListener(object : OnHierarchyChangeListener {
            override fun onChildViewAdded(parent: View, child: View) {
                requestApplyInsets()
            }

            override fun onChildViewRemoved(parent: View, child: View) {

            }
        })
    }

    override fun onApplyWindowInsets(insets: WindowInsets): WindowInsets {
        //对子View进行遍历,逐个分发状态栏空间的适配事件
        for (index in 0 until childCount)
            getChildAt(index).dispatchApplyWindowInsets(insets)
        return insets
    }
}
上一篇 下一篇

猜你喜欢

热点阅读