Ceci est une ancienne révision du document !
Table des matières
Communication
Événements
Seulement en Kotlin.
FragmentResult
Communication en temps réel.
On stocke dans le FragmentManager
une action a effectuée quand une clé est appelée.
Puis on génère une événement avec cette clé avec éventuellement des données associées (ou un Bundle
vide à défaut).
- Génération de l'événement :
getParentFragmentManager().setFragmentResult("key", new Bundle())
- Observateur :
getSupportFragmentManager().setFragmentResultListener("key", this, (requestKey, result) -> {...});
On utilise getSupportFragmentManager()
depuis une activity et getParentFragmentManager
depuis un fragment.
Il est aussi possible d'appeler clearFragmentResultListener
depuis l'action de setFragmentResultListener
si on souhaite, par exemple, que le listener n'écoute que le premier appel.
The right way to get a result. Part 2. Fragment Result API Archive du 31/05/2021 le 22/08/2023
LiveData
Communication en temps réel.
LiveData est un champ qui peut être observé. Il s'implémente sur la base d'une classe ViewModel.
LiveData
(avec ses méthodes observe
, setValue
) s'utilise depuis le thread de l'UI. Sinon, il existe postValue
si on est en dehors du thread de l'UI.
public class ItemViewModel extends ViewModel { private final MutableLiveData<Item> selectedItem = new MutableLiveData<Item>(); public void selectItem(Item item) { selectedItem.setValue(item); } public LiveData<Item> getSelectedItem() { return selectedItem; } }
Ici, Item
est soit une classe contenant une ou plusieurs données, soit la version classe d'un type primitif (Boolean
, Float
, …).
Les données LiveData
sont perdues à la fermeture de l'application.
Si un observateur commence à surveiller un LiveData
et qu'une valeur a déjà été assignée, la callback est immédiatement appelée (depuis le thread de l'UI).
Un LiveData
est commun à tous les éléments ayant le même cycle de vue du constructeur.
- Observateur
Depuis une activity, on utilise this
avec ViewModelProvider
car tous les fragments vont avoir la même Activity.
Depuis un fragment, il faut utiliser requireActivity()
avec ViewModelProvider
.
Pour observe
, il faut utiliser this
avec onCreate
et getViewLifecycleOwner()
avec onViewCreated
et onActivityCreated
. LiveData observing in Fragment Archive du 17/07/2019 le 23/08/2023 The activity lifecycle#oncreate Archive du 24/04/2023 le 23/08/2023 Fragment#getViewLifecycleOwner Archive du 11/08/2023 le 23/08/2023
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); viewModel = new ViewModelProvider(this).get(ItemViewModel.class); viewModel.getSelectedItem().observe(this, item -> { // Perform an action with the latest item data. }); }
- Modificateur
Ici, depuis un fragment, on utilise requireActivity
pour les mêmes raisons que ci-dessus.
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); viewModel = new ViewModelProvider(requireActivity()).get(ItemViewModel.class); ... viewModel.selectItem(item); }
setArguments
Passage de l'information avant le chargement du fragment.
Depuis l'activity ou le fragment parent :
final Bundle bundle = new Bundle(); bundle.putBoolean("param", true); fragment.setArguments(bundle);
Depuis le fragment enfant :
requireArguments().getBoolean("param");
Bouton back
Appel manuel
mainActivity.getSupportFragmentManager().popBackStack();
Changement de fragment
Le comportement du bouton back se définit dans le FragmentManager
au moment du chargement du nouveau fragment.
fragmentManager.beginTransaction()... .addToBackStack(null) .commit();
Puis quand le bouton back sera appelé, les transactions seront inversées jusqu'au précédent appel à addToBackStack
.
Evidemment, il est possible de faire plusieurs addToBackStack
. Il sera alors possible d'appuyer sur le bouton back autant de fois qu'il y aura eu de addToBackStack
. Chaque bouton back remontera d'un cran la pile des transactions.
Depuis onBackPressed event
Dans l'activity, il est possible de surcharger la méthode onBackPressed
. Mais cette méthode est dépréciée.
Il faut utiliser :
getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) { @Override public void handleOnBackPressed() { // Back is pressed... Finishing the activity finish(); } });
onBackPressed() is deprecated. What is the alternative? Archive du 27/07/2023 le 23/08/2023