Fragment出现重叠
来源:3-6 app定制Fragment导航器

慕龙北星
2020-03-12
学习完这一节后Fragment出现了重叠,而且我将其他Fragment设置为启动Fragment后也是这样。FixFragmentNavigator
代码如下:
private const val TAG = "FixFragmentNavigator"
@Navigator.Name("fixfragment")
class FixFragmentNavigator(
private val context: Context,
private val manager: FragmentManager,
private val containerId: Int
) : FragmentNavigator(context, manager, containerId) {
override fun navigate(
destination: Destination,
args: Bundle?,
navOptions: NavOptions?,
navigatorExtras: Navigator.Extras?
): NavDestination? {
if (manager.isStateSaved) {
Log.i(TAG, "Ignoring navigate() call: FragmentManager has already" + " saved its state")
return null
}
var className = destination.className
if (className[0] == '.') {
className = context.packageName + className
}
//由于我们需要重用FragmentManager,所以不需要每次跳转都创建
/* val frag = instantiateFragment(
context, manager,
className, args
)
frag.arguments = args*/
val ft = manager.beginTransaction()
var enterAnim = navOptions?.enterAnim ?: -1
var exitAnim = navOptions?.exitAnim ?: -1
var popEnterAnim = navOptions?.popEnterAnim ?: -1
var popExitAnim = navOptions?.popExitAnim ?: -1
if (enterAnim != -1 || exitAnim != -1 || popEnterAnim != -1 || popExitAnim != -1) {
enterAnim = if (enterAnim != -1) enterAnim else 0
exitAnim = if (exitAnim != -1) exitAnim else 0
popEnterAnim = if (popEnterAnim != -1) popEnterAnim else 0
popExitAnim = if (popExitAnim != -1) popExitAnim else 0
ft.setCustomAnimations(enterAnim, exitAnim, popEnterAnim, popExitAnim)
}
//获取当前活跃的Fragment,并将其隐藏
val fragment = manager.primaryNavigationFragment
fragment?.let { ft.hide(it) }
val tag = destination.id.toString()
var destinationFrg = manager.findFragmentByTag(tag)
when (destinationFrg) {
null -> {
destinationFrg = instantiateFragment(
context, manager,
className, args
)
destinationFrg.arguments = args
ft.add(containerId, destinationFrg, tag)
}
else -> ft.show(destinationFrg)
}
// ft.replace(containerId, frag)
ft.setPrimaryNavigationFragment(destinationFrg)
@IdRes val destId = destination.id
var mBackStack: ArrayDeque<Int> = ArrayDeque()
//通过反射获取Fragment回退栈mBackStack
try {
val field = FragmentNavigator::class.java.getDeclaredField("mBackStack")
field.isAccessible = true
mBackStack = field.get(this) as ArrayDeque<Int>
} catch (e: NoSuchFieldException) {
e.printStackTrace()
} catch (e: IllegalAccessException) {
e.printStackTrace()
}
val initialNavigation = mBackStack.isEmpty()
val isSingleTopReplacement = (navOptions != null && !initialNavigation
&& navOptions.shouldLaunchSingleTop()
&& mBackStack.peekLast() == destId)
val isAdded: Boolean
if (initialNavigation) {
isAdded = true
} else if (isSingleTopReplacement) {
// Single Top means we only want one instance on the back stack
if (mBackStack.size > 1) {
// If the Fragment to be replaced is on the FragmentManager's
// back stack, a simple replace() isn't enough so we
// remove it from the back stack and put our replacement
// on the back stack in its place
manager.popBackStack(
generateBackStackName(mBackStack.size, mBackStack.peekLast()),
FragmentManager.POP_BACK_STACK_INCLUSIVE
)
ft.addToBackStack(generateBackStackName(mBackStack.size, destId))
}
isAdded = false
} else {
ft.addToBackStack(generateBackStackName(mBackStack.size + 1, destId))
isAdded = true
}
if (navigatorExtras is Extras) {
val extras = navigatorExtras as Extras?
for ((key, value) in extras!!.sharedElements) {
ft.addSharedElement(key, value)
}
}
ft.setReorderingAllowed(true)
ft.commit()
// The commit succeeded, update our view of the world
return if (isAdded) {
mBackStack.add(destId)
destination
} else {
null
}
}
private fun generateBackStackName(backStackIndex: Int, destid: Int): String {
return "$backStackIndex-$destid"
}
}
写回答
1回答
-
LovelyChubby
2020-03-13
好的,我来看看,可能不好复现
022020-06-11
相似问题