Как мне добавить фоновый пакет навигации Android к определенному фрагменту?

#android #kotlin #navigation #fragment-backstack

#Android #kotlin #навигация #фрагмент-фоновый пакет

Вопрос:

Я еще раз прошу вашей интеллектуальной поддержки.

У меня есть фрагмент, который помещает несколько своих копий в фоновый пакет навигации следующим образом:

 Navigation.findNavController(button).navigate(
    TaskCollectFragmentDirections.actionTaskCollectFragmentSelf(args.taskIndex, args.screenIndex   1)
)
 

Приведенный выше код работает так, как задумано.

Проблема возникает, когда я хочу удалить указанное количество этих фрагментов из фонового пакета навигации. (Запускается нажатием кнопки.)

Я пытался сделать это так:

 Navigation.findNavController(button).popBackStack(lastRecurringFragmentId, false)
 

Мой код компилируется и запускается, но просто ничего не делает. Когда я не даю никаких параметров popBackStack функции, она правильно выскакивает из самого верхнего фрагмента. Я также могу использовать стрелку назад, чтобы вернуться к исходному фрагменту.

Если это имеет какое-либо значение, lastRecurringFragmentId это происходит из этой функции:

 fun getLastRecurringFragmentId(recurringFragmentCount: Int): Int {
    val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment)!!
    val backStackEntryCount = navHostFragment.childFragmentManager.backStackEntryCount
    val indexOfRequested = backStackEntryCount - recurringFragmentCount
    val requestedEntry = navHostFragment.childFragmentManager.getBackStackEntryAt(indexOfRequested)
    return requestedEntry.id
}
 

График навигации выглядит следующим образом. Предполагается, что их должно быть несколько TaskCollectFragment , и, наконец, один TaskEndFragment в верхней части фонового пакета. Я хочу удалить некоторые TaskCollectFragment элементы из стека, когда пользователь нажимает кнопку на TaskEndFragment :

 <navigation 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:id="@ id/mobile_navigation"
    app:startDestination="@id/nav_home">

    <fragment
        android:id="@ id/nav_home"
        android:name="ui.home.HomeFragment"
        android:label="@string/menu_home"
        tools:layout="@layout/fragment_home" >
        <action
            android:id="@ id/action_nav_home_to_taskCollectFragment"
            app:destination="@id/taskCollectFragment" />
    </fragment>

    <fragment
        android:id="@ id/taskCollectFragment"
        android:label="TaskCollectFragment"
        tools:layout="@layout/task_collect_fragment"
        >
        <action
            android:id="@ id/action_taskCollectFragment_to_taskEndFragment"
            app:destination="@id/taskEndFragment" />
        <action
            android:id="@ id/action_taskCollectFragment_self"
            app:destination="@id/taskCollectFragment" />
        <argument
            android:name="taskIndex"
            app:argType="integer" />
        <argument
            android:name="screenIndex"
            app:argType="integer" />
    </fragment>
    <fragment
        android:id="@ id/taskEndFragment"
        android:name="ui.task.TaskEndFragment"
        android:label="TaskEndFragment"
        tools:layout="@layout/task_end_fragment">
        <argument
            android:name="taskIndex"
            app:argType="integer" />
    </fragment>
</navigation>
 

Есть ли способ, которым я могу извлекать фрагменты из фонового пакета, пока не будет выполнено определенное условие?

Комментарии:

1. Ваш getLastRecurringFragmentId() не имеет никакого смысла при использовании навигации — идентификаторы, которые вы передаете popBackStack() , — это android:id s в вашем навигационном графике. Можете ли вы включить свой навигационный график?

2. @ianhanniballake Означает ли это, что я не могу различать несколько экземпляров фрагмента?

3. Может быть, было бы лучше, если бы вы сказали, каким должен быть ваш стек после pop? Вы хотите, чтобы все ваши экземпляры taskCollectFragment были извлечены, и только те nav_home , которые все еще находятся в стеке?

4. @ianhanniballake Как я уже сказал, я хочу добавить некоторые из taskCollectFragment них. Может быть, всего несколько, может быть, все, это зависит от обстоятельств. Спасибо, что сообщили мне об источнике идентификаторов, это дало мне идею!

Ответ №1:

Я создал два почти идентичных фрагмента forSessionTaskCollectFragment и recurringTaskCollectFragment с той же ViewModel. Они выглядят одинаково, и с точки зрения пользователя они делают то же самое. forSessionTaskCollectFragment s — это те, которые я хочу сохранить, а recurringTaskCollectFragment s — это те, которые я хочу вернуть позже.

Из домашнего фрагмента мой навигационный график переходит в forSessionTaskCollectFragment , оттуда он возвращается к себе или переходит к recurringTaskCollectFragment , который также возвращается к себе или, наконец, переходит к TaskEndFragment

 <fragment
    android:id="@ id/nav_home"
    android:name="ui.home.HomeFragment"
    android:label="@string/menu_home"
    tools:layout="@layout/fragment_home" >
    <action
        android:id="@ id/action_nav_home_to_orSessionTaskCollectFragment"
        app:destination="@id/forSessionTaskCollectFragment" />
</fragment>

<fragment
    android:id="@ id/forSessionTaskCollectFragment"
    android:name="ui.task.ForSessionTaskCollectFragment"
    android:label="ForSessionTaskCollectFragment" >
    <action
        android:id="@ id/action_forSessionTaskCollectFragment_self"
        app:destination="@id/forSessionTaskCollectFragment" />
    <action
        android:id="@ id/action_forSessionTaskCollectFragment_to_recurringTaskCollectFragment"
        app:destination="@id/recurringTaskCollectFragment" />
    <argument
        android:name="taskIndex"
        app:argType="integer" />
    <argument
        android:name="screenIndex"
        app:argType="integer" />
</fragment>

<fragment
    android:id="@ id/recurringTaskCollectFragment"
    android:name="ui.task.RecurringTaskCollectFragment"
    android:label="TaskCollectFragment"
    tools:layout="@layout/recurring_task_collect_fragment"
    >
    <action
        android:id="@ id/action_recurringTaskCollectFragment_to_taskEndFragment"
        app:destination="@id/taskEndFragment" />
    <action
        android:id="@ id/action_recurringTaskCollectFragment_self"
        app:destination="@id/recurringTaskCollectFragment" />
    <argument
        android:name="taskIndex"
        app:argType="integer" />
    <argument
        android:name="screenIndex"
        app:argType="integer" />
</fragment>
 

Я помещаю forSessionTaskCollectFragment s в стек, пока не дойду до точки, к которой хочу вернуться.

 Navigation.findNavController(button).navigate(
    if(args.screenIndex < viewModel.forSessionScreenCount) {
        ForSessionTaskCollectFragmentDirections.actionForSessionTaskCollectFragmentSelf(args.taskIndex, args.screenIndex   1)
    } else {
        ForSessionTaskCollectFragmentDirections.actionForSessionTaskCollectFragmentToRecurringTaskCollectFragment(args.taskIndex, args.screenIndex   1)
    }
)
 

После этого я помещаю фрагменты, которые позже захочу вставить обратно, и, наконец, перехожу к тому TaskEndFragment месту, откуда я хочу вставить нужные фрагменты:

 Navigation.findNavController(button).navigate(
    if(args.screenIndex < viewModel.screenCount - 2) {
        RecurringTaskCollectFragmentDirections.actionRecurringTaskCollectFragmentSelf(args.taskIndex, args.screenIndex   1)
    } else {
        RecurringTaskCollectFragmentDirections.actionRecurringTaskCollectFragmentToTaskEndFragment(args.taskIndex)
    }
)
 

Итак, при нажатии кнопки TaskEndFragment «s» я могу вернуться к точному месту в фоновом стеке, которое я пометил переходом с фрагментов «сеанса» на «повторяющиеся» фрагменты:

 Navigation.findNavController(button).popBackStack(R.id.forSessionTaskCollectFragment, false)
 

Это было много хлопот, я не нашел ни одного примера для того, что я хотел сделать, но, наконец, удалось найти рабочее решение. Ianhanniballake еще раз спасибо, вы вызвали мою идею.

Комментарии:

1. Привет, o /. Это не ответ на вопрос, который вы задали. Вместо того, чтобы фактически вернуться к определенному фрагменту, вы перемещаетесь вперед.

2. Есть какие-либо объяснения? Все работает так, как ожидалось. Я предлагаю вам внимательно прочитать все это. Я перемещаюсь вперед, пока добавляю фрагменты. Хитрость заключается в том, чтобы изменить тип фрагмента, который я добавляю в тот момент, когда я хочу вернуться. Затем, когда мне нужно вернуться, я могу сделать это, вызвав «Navigation.findNavController(button).popBackStack(R.id.forSessionTaskCollectFragment, false)» Я почти уверен, что я не продвигаюсь вперед, делая это.