Androidx - Как обрабатывать фрагменты Nested Graph из родительского фрагмента с помощью Navigation? - PullRequest
0 голосов
/ 24 сентября 2019

enter image description here

Вот сценарий: -

У меня есть основное действие, у которого есть корневой NavGraph и загрузка фрагмента A по умолчанию.Если я перемещаюсь из фрагмента A во фрагмент B, где у меня есть дочерний фрагмент и TabLayout внутри него, пользователь может переключать фрагмент внутри него, для чего я создал новый вложенный граф для дочернего фрагмента внутри фрагмента B. Когда я перемещаюсь из фрагментаОт A до фрагмента B, я могу показать фрагмент C внутри моего дочернего фрагмента, потому что я установил начальное назначение в качестве фрагмента C на моем вложенном графике.

***root Navigation Graph***



     <?xml version="1.0" encoding="utf-8"?>
    <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/navigation_graph"
                app:startDestination="@id/fragmentC">

        <fragment
                android:id="@+id/FragmentA"
                android:name="com.myapp.fragment.FragmentA"
                android:label="Fragment A"
                tools:layout="@layout/fragment_A">
            <action
                    android:id="@+id/action_fragmentA_to_fragmentB"
                    app:destination="@id/fragmentB" />
        </fragment>
        <fragment
                android:id="@+id/fragmentB"
               android:name="com.myapp.fragment.FragmentB"
                android:label="FragmentB"
                tools:layout="@layout/fragment_B">
            <action
                    android:id="@+id/action_fragmentB_to_second_graph"
                    app:destination="@id/navigation_graph2" />
        </fragment>

        <include app:graph="@navigation/navigation_graph2" />

    </navigation>


    ***Nested Navigation Graph***


        <?xml version="1.0" encoding="utf-8"?>
        <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/navigation_graph2"
                    app:startDestination="@id/FragmentC">

            <fragment android:id="@+id/FragmentC"
                      android:name="com.myapp.fragment.FragmentC"
                      android:label="Fragment C"
                      tools:layout="@layout/fragment_C">
 <action
                android:id="@+id/action_fragmentC_fragmentD"
                app:destination="@id/FragmentD" />
            </fragment>

            <fragment android:id="@+id/FragmentD"
                      android:name="com.myapp.fragment.FragmentD"
                      android:label="Fragment D"
                      tools:layout="@layout/fragment_D">
 <action
                android:id="@+id/action_fragmentD_fragmentC"
                app:destination="@id/FragmentC" />
            </fragment>
        </navigation>

***Inside Fragment B***

public class FragmentB extends BaseFragment<FragmentAssignmentsBinding>
        implements TabLayout.OnTabSelectedListener{

    NavController nestedNavController;

    @Override
    public int getLayoutId() {
        return R.layout.fragment_assignments;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        if(getFragmentDataBinding()==null)
            return;
        nestedNavController = Navigation.findNavController(view);
        getFragmentDataBinding().myTabLayout.addOnTabSelectedListener(this);
    }



    @Override
    public void onTabSelected(TabLayout.Tab tab) {

        switch (tab.getPosition()) {
            case 0:
  //***Here  how to handle the nested graph Fragment Action ?***      
             nestedNavController.navigate(R.id. action_fragmentC_fragmentD);
break;
            case 1:
                 nestedNavController.navigate(R.id. action_fragmentD_fragmentC);
                break;
        }

    }

    @Override
    public void onTabUnselected(TabLayout.Tab tab) {

    }

    @Override
    public void onTabReselected(TabLayout.Tab tab) {

    }
}

Теперь проблема в том, что -> OnClicking Tab A или Tab Bиз parentFragment (Fragment B) я должен получить доступ к вложенным действиям NavGraph для замены фрагмента внутри parentFragment. Но возникает ошибка: -

java.lang.IllegalArgumentException: назначение навигации com.myapp: id /action_fragmentC_fragmentD неизвестен этому NavController

Любая помощь или руководство будет действительно полезным.

Ответы [ 2 ]

1 голос
/ 24 сентября 2019

В вашем фрагменте B макета у вас должно быть что-то вроде:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <android.support.design.widget.TabLayout  
        android:id="@+id/tabLayout"  
        android:layout_width="match_parent"  
        android:layout_height="wrap_content"  
        android:background="#1db995">  
    </android.support.design.widget.TabLayout>  

    <android.support.v4.view.ViewPager  
        android:id="@+id/viewPager"  
        android:layout_width="355dp"  
        android:layout_height="455dp"  
        app:layout_constraintTop_toBottomOf="@+id/tabLayout"  
        tools:layout_editor_absoluteX="8dp" /> 

    <fragment
        android:id="@+id/base_container"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="@dimen/dimen_constraint"
        app:defaultNavHost="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/activity_base_toolbar_main"
        app:navGraph="@navigation/navigation_graph2" />
    ...

public class FragmentB extends ...
...

@Override
public void onTabSelected(TabLayout.Tab tab) {
    controller = findNavController(R.id.base_container)
    switch (tab.getPosition()) {
        case 0:
            controller.navigate(R.id.action_fragmentC_fragmentD);
        break;
        case 1:
            controller.navigate(R.id.action_fragmentD_fragmentC);
            break;
    }

}
...

Или в качестве обходного пути вы можете рассмотреть возможность использования BottomNavigationView для воспроизведения того же поведения TabLayout

0 голосов
/ 24 сентября 2019

Цитирование Ответ Яна Лейка

Согласно этой проблеме :

Навигация фокусируется на элементах, которые влияют на задний стек и вкладкине влияют на задний стек - вы должны продолжать управлять вкладками с помощью ViewPager и TabLayout

Таким образом, вы должны использовать ViewPager с tablayout, а не вложенным графом навигации.

Пожалуйста, посмотрите на ветвь табуляции для рабочего примера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...