Navigating to preference fragment using navigation component
Asked Answered
D

4

24

I'm trying to migrate my medium sized app to the new Android navigation component.

Currently, my app consists of the single activity and I'm planning on keeping it the same (for that matter); So, I'm facing this issue in which I have a settings fragment (PreferenceFragment) that can be navigated to, basically, from every other fragment. This navigation is made through a menu in the app bar, therefore onOptionsItemSelected (containing this navigation) is in the main activity.

Navigation graph

I'm having trouble figuring what is the right way to connect the settingsFragment to the other ones. Connecting it to all others seems like spaghetti to me.

  1. Should settingsFragment be connected to all another fragment?

  2. Should I abandon the single activity application architecture since Google isn't giving enough reasons (or any reasons) to support it?

Daniels answered 28/10, 2018 at 8:53 Comment(0)
E
41

To deal with your problem, you can use global actions. To use them you need to define action inside <navigation> tag, not inside <fragment> as you usually do. Your nav graph will contain the next code

<?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">

    <!--Your other fragments-->

    
    <!--Settings fragment-->
    <fragment
        android:id="@+id/settingsFragment"
        android:name="com.example.oleksii.stackoverflow.SettingsFragment"/>

    <!--Global action-->
    <action android:id="@+id/open_settings_fragment"
        app:destination="@id/settingsFragment"/>
</navigation>

In the graph editor it will be displayed in the next way (just arrow in the left of destination):

enter image description here

More details: https://developer.android.com/topic/libraries/architecture/navigation/navigation-global-action

Emersed answered 30/10, 2018 at 14:20 Comment(3)
if i had multiple graph and need to use a global action, how to access it from other fragments?Quantitative
Why do I get an error: ID does not reference a View inside this Activity?Detroit
The OP's link now redirects to this: developer.android.com/guide/navigation/navigation-global-action (pasting it in case the old link becomes out of date some day)Natividadnativism
C
6

I can navigate to another fragment or preference fragment using following approach:

Global Settings Fragment:

<PreferenceCategory
    app:title="@string/global_settings_header">
    <Preference
        app:key="fragment_a"
        app:title="A"
        app:fragment="....settings.SettingsFragmentA" />
    <Preference
        app:key="fragment_b"
        app:title="B"
        app:fragment=".....settings.SettingsFragmentB" />
</PreferenceCategory>

Implemented PreferenceFragmentCompat.OnPreferenceStartFragmentCallback in activity.

public class MainActivity extends AppCompatActivity implements PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {
....

@Override
public boolean onPreferenceStartFragment(PreferenceFragmentCompat caller, Preference pref) {
    NavController navController = Navigation.findNavController(MainActivity.this, R.id.nav_host_fragment);
    if (pref.getKey().equals("fragment_a")) {
        navController.navigate(R.id.nav_settings_fragment_a);
    } else if (pref.getKey().equals("fragment_b")) {
        navController.navigate(R.id.nav_settings_fragment_b);
    }
    return true;
}

....
}

I can also navigate to any fragment that is defined in the navigation graph using NavController.

Any fragment can be used in app:fragment=".....settings.SettingsFragment". The idea is to trigger the onPreferenceStartFragment callback.

Cyprinid answered 28/3, 2020 at 16:8 Comment(0)
C
5

but if your preferences are hierarchical you get Fragment <insert fragment name here> declared target fragment <guid> that does not belong to this FragmentManager! when you click on a child preference.

i have not found a solution to this yet.

Coordination answered 19/11, 2018 at 14:48 Comment(3)
Did you figure out a solution?Peppi
override getCallbackFragment and implement onPreferenceStartFragmentCallback, there you have to do your custom fragment starting e.g. with navControllerSeabrooke
#63305540Potaufeu
P
0

To build on the answer from @Alexey, to invoke the global action, you can use code like this:

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    int id = item.getItemId();
    if (id == R.id.action_settings) {
        Navigation.findNavController(this, R.id.nav_host_fragment).navigate(R.id.settingsFragment);
    }
    return super.onOptionsItemSelected(item);
}
Phenomenal answered 24/3, 2020 at 13:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.