第一个坑,多Fragment嵌套ViewPager2,偶尔会奔溃,报错信息
解决办法
viewPager2.isSaveEnabled = false
复制代码
但是你可能发现切换界面每次会重新创建一个fragment
解决办法
// 把 beginTransaction.replace 替换成 hide show
val beginTransaction = fragmentManager.beginTransaction()
var hasFragment = false
fragmentManager.fragments.forEach {
it?.let {
beginTransaction.hide(it)
if(it == fragment){
hasFragment = true
}
}
}
if(!hasFragment){
beginTransaction.add(containerViewId,fragment,tag)
}else{
beginTransaction.show(fragment)
}
复制代码
然后如果你的多个fragment 中fitsSystemWindows不一致,也就是说有的是true ,有的是false,别问我为什么这样,设计如此
查源码,当第一个Fragment添加到Activity中的时候,Activity寻找出有fitsSystemWindows的子布局为其预留出状态栏的空间,其实就是设置一个padding,而其他Fragment添加到Activity中的时候,因为状态栏空间的适配已经被消费过一次了,Activity并不会再次去添加这个padding。因此我们需要自定义一个FrameLayout,重写它的状态栏空间适配的时机和它的适配事件的分发 ,所以我们重写FrameLayout,网上找的代码无效,自己研究了一下,要在测量前将fitSystemWindows值传递给子布局,代码如下
import android.annotation.SuppressLint
import android.annotation.TargetApi
import android.content.Context
import android.graphics.Rect
import android.os.Build
import android.util.AttributeSet
import android.view.WindowInsets
import android.widget.FrameLayout
import androidx.core.util.ObjectsCompat
/**
* description:谷歌bug,重写FrameLayout,在测量前将fitSystemWindows值传递给子布局
* version: 1.0
*/
class WindowInsetsFrameLayout : FrameLayout {
private var mLastInsets: Any? = null
constructor(context: Context?) : super(context!!)
constructor(context: Context?, attrs: AttributeSet?) : super(context!!, attrs)
constructor(context: Context?, attrs: AttributeSet?, defStyle: Int) : super(
context!!,
attrs,
defStyle
)
@TargetApi(Build.VERSION_CODES.KITKAT_WATCH)
override fun onApplyWindowInsets(insets: WindowInsets): WindowInsets {
if (!ObjectsCompat.equals(mLastInsets, insets)) {
mLastInsets = insets
requestLayout()
}
return insets.consumeSystemWindowInsets()
}
override fun fitSystemWindows(insets: Rect): Boolean {
if (!ObjectsCompat.equals(mLastInsets, insets)) {
if (mLastInsets == null) {
mLastInsets = Rect(insets)
} else {
(mLastInsets as Rect).set(insets)
}
requestLayout()
}
return true
}
@SuppressLint("DrawAllocation")
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
if (mLastInsets != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
val wi = mLastInsets as WindowInsets
val childCount = childCount
for (i in 0 until childCount) {
val child = getChildAt(i)
if (child.visibility != GONE) {
child.dispatchApplyWindowInsets(wi)
}
}
} else {
super.fitSystemWindows(Rect(mLastInsets as Rect?))
}
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
}
}
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END