Как использовать навигацию с компонентами навигации и меню ящика? - PullRequest
0 голосов
/ 24 апреля 2020

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

 Set<Integer> topLevelDestinations = new HashSet<>();
        topLevelDestinations.add(R.id.schedulesFragment);
        topLevelDestinations.add(R.id.backpacksFragment);
        topLevelDestinations.add(R.id.itemsFragment);



        appBarConfiguration = new AppBarConfiguration.Builder(topLevelDestinations)
                .setDrawerLayout(drawerLayout)
                .build();

        NavigationUI.setupWithNavController(navigationView, navController);
        NavigationUI.setupActionBarWithNavController(this,navController,appBarConfiguration);

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

 smartPackViewModel = ViewModelProvider.AndroidViewModelFactory.getInstance(requireActivity().getApplication()).create(SmartPackViewModel.class);
        smartPackViewModel.getFoundSmartPack().observe(getViewLifecycleOwner(), new Observer<BluetoothDevice>() {
            @Override
            public void onChanged(BluetoothDevice bluetoothDevice) {
                if(navController != null){
             navController.navigate(R.id.action_backpacksFragment_to_newSmartPackFoundFragment);
                }
            }
        });

Этот код работает, и как только я перехожу к NewSmartPackFoundFragment, кнопка гамбургера превращается в кнопку «вверх», что я и собираюсь сделать. Проблема в том, что нажатие кнопки вверх не возвращает меня к предыдущему фрагменту, оно ничего не делает, и кнопка назад тоже ничего не делает. Я попытался переопределить onSupportNavigateUp и из-за журнала, который я использую, я знаю, что метод вызывается, но ничего по-прежнему ничего не происходит:

    @Override
    public boolean onSupportNavigateUp() {
        Log.d("NAVIGATE", "onNavigateUp was called" );
        return NavigationUI.navigateUp(navController,appBarConfiguration);
    }

Я также пытался использовать navigate() внутри этого метода без каких-либо результатов:

@Override
    public boolean onSupportNavigateUp() {
        Log.d("NAVIGATE", "onNavigateUp was called" );
        navController.navigate(R.id.action_newSmartPackFoundFragment_to_backpacksFragment2);
       return NavigationUI.navigateUp(navController,appBarConfiguration);
    }

Я посмотрел в Интернете, в чем проблема, но пока не могу понять. Это мой макет деятельности:

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:id="@+id/logged_in_activity_drawer_layout"
    android:fitsSystemWindows="true">

 <LinearLayout
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:orientation="vertical">


         <com.google.android.material.appbar.AppBarLayout
             android:layout_width="match_parent"
             android:layout_height="?actionBarSize">

             <androidx.appcompat.widget.Toolbar
                 android:id="@+id/logged_in_activity_toolbar"
                 android:layout_width="match_parent"
                 android:layout_height="?android:attr/actionBarSize"/>
     </com.google.android.material.appbar.AppBarLayout>

и это мои зависимости:

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])


    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
    implementation 'com.google.android.material:material:1.1.0'
    implementation 'androidx.recyclerview:recyclerview:1.2.0-alpha02'
    implementation 'com.google.firebase:firebase-auth:19.3.0'
    implementation 'com.google.firebase:firebase-analytics:17.3.0'
    implementation 'com.google.firebase:firebase-firestore:21.4.2'
    implementation "androidx.navigation:navigation-fragment:2.2.2"
    implementation "androidx.navigation:navigation-ui:2.2.2"
}

Заранее большое спасибо!

РЕДАКТИРОВАТЬ

Вот так выглядит мой навигационный график:

<?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/nav_graph_logged_in"
    app:startDestination="@id/backpacksFragment">
    <fragment
        android:id="@+id/backpacksFragment"
        android:name="com.pedroprojects.smartpack.Fragments.BackpacksFragment"
        android:label="fragment_backpacks"
        tools:layout="@layout/fragment_backpacks"

        >
        <action
            android:id="@+id/action_backpacksFragment_to_backpackDetailsFragment"
            app:destination="@id/backpackDetailsFragment" />
        <action
            android:id="@+id/action_backpacksFragment_to_newSmartPackFoundFragment"
            app:destination="@id/newSmartPackFoundFragment"
            app:launchSingleTop="true"
            app:popUpTo="@id/backpacksFragment"
            app:popUpToInclusive="false" />

    </fragment>
    <fragment
        android:id="@+id/itemsFragment"
        android:name="com.pedroprojects.smartpack.Fragments.ItemsFragment"
        android:label="fragment_items"
        tools:layout="@layout/fragment_items" />
    <fragment
        android:id="@+id/schedulesFragment"
        android:name="com.pedroprojects.smartpack.Fragments.SchedulesFragment"
        android:label="fragment_schedules"
        tools:layout="@layout/fragment_schedules" />
    <fragment
        android:id="@+id/backpackDetailsFragment"
        android:name="com.pedroprojects.smartpack.Fragments.BackpackDetailsFragment"
        android:label="fragment_backpack_details"
        tools:layout="@layout/fragment_backpack_details" />
    <fragment
        android:id="@+id/newSmartPackFoundFragment"
        android:name="com.pedroprojects.smartpack.Fragments.NewSmartPackFoundFragment"
        android:label="fragment_new_smart_pack_found"
        tools:layout="@layout/fragment_new_smart_pack_found" >
        <action
            android:id="@+id/action_newSmartPackFoundFragment_to_backpacksFragment2"
            app:destination="@id/backpacksFragment" />
    </fragment>

</navigation>

1 Ответ

0 голосов
/ 24 апреля 2020

Вам необходимо проверить атрибуты app:popUpTo & app:popUpToInclusive фрагмента NavigationDrawer, которые вы используете для перехода к NewSmartPackFoundFragment.

И вы можете проверить это непосредственно из файла графика навигации xml под этим конкретным фрагментом, и, в частности, в рамках действия, которое вы используете для go до NewSmartPackFoundFragment фрагмента с идентификатором R.id.action_backpacksFragment_to_newSmartPackFoundFragment в вашем случае.

Убедитесь, что для app:popUpToInclusive установлено значение false, чтобы избежать очистки стека навигации.

И установите app:popUpTo на фрагмент, который вы хотите получить, когда вы нажимаете кнопку вверх / назад после перехода на NewSmartPackFoundFragment.

Я приведу пример, поскольку вы не поделились графиком навигации.

<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/..."
    app:startDestination="@+id/...">

    <fragment
        android:id="@+id/backpacksFragment"
        android:name="..."
        android:label="..."
        tools:layout="..." >
        <action
            android:id="@+id/action_backpacksFragment_to_newSmartPackFoundFragment"
            app:destination="@id/..."
            app:popUpTo="@id/nav_backpacksFragment"
            app:popUpToInclusive="false" />
    </fragment>   

Обновление 1: Я попробовал то, что вы предложили, с помощью popUpTo и popUpToInclusive но у меня все еще есть та же проблема

Теперь измените onSupportNavigateUp() в вашей активности, которая вызывается всякий раз, когда пользователь выбирает для навигации вверх по иерархии действий вашего приложения от панели действий.

N Теперь измените этот метод, в котором размещены эти фрагменты:

@Override
public boolean onSupportNavigateUp() {
    NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
    return NavigationUI.navigateUp(navController, appBarConfiguration)
            || super.onSupportNavigateUp();
}

Теперь замените R.id.nav_host_fragment на идентификатор фрагмента хоста в макете вашей активности

...