J'essaie de migrer mon application de taille moyenne vers le nouveau composant Android navigation
.
Actuellement, mon application se compose de single activity
et je prévois de garder les mêmes (d'ailleurs); Donc, je suis confronté à ce problème dans lequel j'ai un fragment de paramètres (PreferenceFragment
) qui peut être parcouru, essentiellement, à partir de tous les autres fragments. Cette navigation se fait via un menu dans la barre d'application, donc onOptionsItemSelected
(contenant cette navigation) est dans l'activité principale.
J'ai du mal à déterminer quelle est la bonne façon de connecter le settingsFragment
aux autres. Le connecter à tous les autres me semble être un spaghetti.
settingsFragment
doit-il être connecté à tout autre fragment?
Dois-je abandonner l'architecture d'application à activité unique, car Google ne donne pas suffisamment de raisons (ou aucune raison) pour la prendre en charge?
Pour résoudre votre problème, vous pouvez utiliser global actions
. Pour les utiliser, vous devez définir une action à l'intérieur de <navigation>
tag, pas à l'intérieur <fragment>
comme d'habitude. Votre graphique de navigation contiendra le code suivant
<?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>
Dans l'éditeur de graphique, il sera affiché de la manière suivante (juste une flèche à gauche de destination
):
Plus de détails: https://developer.Android.com/topic/libraries/architecture/navigation/navigation-global-action
mais si vos préférences sont hiérarchiques, vous obtenez Fragment <insert fragment name here> declared target fragment <guid> that does not belong to this FragmentManager!
lorsque vous cliquez sur une préférence enfant.
je n'ai pas encore trouvé de solution à cela.
Je peux naviguer vers un autre fragment ou fragment de préférence en utilisant l'approche suivante:
Fragment des paramètres globaux:
<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>
Mis en œuvre PreferenceFragmentCompat.OnPreferenceStartFragmentCallback
en activité.
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;
}
....
}
Je peux également naviguer vers n'importe quel fragment défini dans le graphique de navigation à l'aide de NavController.
Tout fragment peut être utilisé dans app:fragment=".....settings.SettingsFragment"
. L'idée est de déclencher le callback onPreferenceStartFragment
.
Pour s'appuyer sur la réponse de @Alexey, pour appeler l'action globale, vous pouvez utiliser du code comme celui-ci:
@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);
}