Navigation#popBackStack收获

Navigation#popBackStack收获

findNavController().navigateUp()

Navigation管理的Fragment中可以通过navigateUp返回上一页,这里可以先从navigateUp入手,看下其源码:

    public boolean navigateUp() {
    
    
        if (getDestinationCountOnBackStack() == 1) {
    
    
           // emmm,略去一大坨 
            return false;
        } else {
    
    
            return popBackStack();
        }
    }

从getDestinationCountOnBackStack的方法名以及if语句的判断条件来看当前任务栈中只有一个fragment时才走这里,猜测是结束当前Activity的操作这里不深入探究。

看下else内的逻辑,调用了popBackStack()方法,继续深究吧 ->

    public boolean popBackStack() {
    
    
        if (mBackStack.isEmpty()) {
    
    
            // Nothing to pop if the back stack is empty
            return false;
        }
        // Pop just the current destination off the stack
        return popBackStack(getCurrentDestination().getId(), true);
    }

这个方法也很简单,当任务栈不为空时直接调用popBackStack的两个参数重载方法,并且第一个参数我们能够看懂传递的是当前fragment目的地的id。

继续深究->

/**
Attempts to pop the controller's back stack back to a specific destination.
Params:  destinationId – The topmost destination to retain
           inclusive – Whether the given destination should also be popped.
Returns: true if the stack was popped at least once and the user has been navigated to another
         destination, false otherwise
* */
    public boolean popBackStack(@IdRes int destinationId, boolean inclusive) {
    
    
        boolean popped = popBackStackInternal(destinationId, inclusive);
        // Only return true if the pop succeeded and we've dispatched
        // the change to a new destination
        return popped && dispatchOnDestinationChanged();
    }

妹的不翻译了,解释的够清楚了。注意下inclusive这个参数很有意思,借助这个参数我们能够实现若干个页面弹出栈的功能。假如有页面FragmentA -> FragmentB -> FragmentC ->FragmentD 目前停留在FragmentD页面:

1、想要关闭当前FragmentD页面
findNavController().apply {
    
    
    popBackStack(currentDestination!!.id,true)
}

哈哈哈哈,这不就是navigateUp 站内非空走的逻辑嘛~

2、想要从当前FragmentD跳转到FragmentB,且FragmentC、FragmentD 出站
 //做法1
 popBackStack(destinationBId, false) 
 //做法2
 popBackStack(destinationCId, true)

有两种做法:

第一种做法是直接跳到FragmentB,inclusive 设置为false 不让FragmentB出栈即可。FragmentC、FragmentD自动出站的。

第二种做法是直接跳到FragmentC,inclusive 设置为true 让FragmentC出栈即可,这样就自动把FragmentB放到栈顶了,FragmentD自动出站的。

猜你喜欢

转载自blog.csdn.net/qq_38350635/article/details/128256079