Les deux révisions précédentesRévision précédenteProchaine révision | Révision précédente |
lang:android:fragment [2023/08/23 09:11] – [LiveData] : mise à jour avec la contrainte du thread de l'UI root | lang:android:fragment [2023/08/23 12:15] (Version actuelle) – Ajout de "Binding" root |
---|
| |
[[https://developer.android.com/guide/fragments/communicate?hl=fr#java|Communiquer avec des fragments]] {{ :lang:android:fragment:communiquer_avec_des_fragments_android_developers_22_08_2023_16_08_14_.html |Archive du 30/05/2023 le 22/08/2023}} | [[https://developer.android.com/guide/fragments/communicate?hl=fr#java|Communiquer avec des fragments]] {{ :lang:android:fragment:communiquer_avec_des_fragments_android_developers_22_08_2023_16_08_14_.html |Archive du 30/05/2023 le 22/08/2023}} |
| |
| Le respect des bonnes pratiques de communication devrait permettre de ne pas avoir besoin d'utiliser ''runOnUiThread(...)''. |
| ====Événements==== |
| |
| Seulement en Kotlin. |
| |
| [[https://developer.android.com/topic/architecture/ui-layer/events?hl=fr|Événements de l'UI]] {{ :lang:android:fragment:v_nements_de_l_ui_android_developers_23_08_2023_09_20_10_.html |Archive du 27/07/2023 le 23/08/2023}} |
| |
====FragmentResult==== | ====FragmentResult==== |
| |
| Communication en temps réel. |
| |
On stocke dans le ''FragmentManager'' une action a effectuée quand une clé est appelée. | On stocke dans le ''FragmentManager'' une action a effectuée quand une clé est appelée. |
| |
====LiveData==== | ====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 est un champ qui peut être observé. Il s'implémente sur la base d'une classe ViewModel. |
| |
<WRAP center round important 60%> | |
''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. | |
</WRAP> | |
| |
| |
<code java> | <code java> |
</code> | </code> |
| |
| * Notes |
| |
| ''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. |
| |
| Il n'est pas possible de modifier ou d'observer uniquement un champ d'un item. Si c'est nécessaire, il faut passer par 2 variables ''LiveData'' différentes. |
| |
| Si un ''LiveData'' est modifié 2 fois avant qu'un observateur soit notifié, l'observateur ne verra que la dernière valeur. |
| |
| Il n'est pas possible d'enlever une valeur à un ''LiveData''. Donc si un observateur observe un ''LiveData'' qui n'a jamais été écrit, aucun événement instantané ne sera généré. Mais si une valeur a déjà été assignée, un événement instantané sera systématiquement généré. |
| |
| <blockquote>If LiveData already has data set, it will be delivered to the observer<cite>[[https://developer.android.com/reference/androidx/lifecycle/LiveData#observe(androidx.lifecycle.LifecycleOwner,androidx.lifecycle.Observer%3C?%20super%20T%3E)|LiveData]] {{ :lang:android:fragment:livedata_android_developers_23_08_2023_11_46_53_.html |Archive du 11/08/2023 le 23/08/2023}}</cite></blockquote> |
| |
| |
| ====setArguments==== |
| |
| Passage de l'information avant le chargement du fragment. |
| |
| Depuis l'activity ou le fragment parent : |
| |
| <code java> |
| final Bundle bundle = new Bundle(); |
| bundle.putBoolean("param", true); |
| fragment.setArguments(bundle); |
| </code> |
| |
| Depuis le fragment enfant : |
| |
| <code java> |
| requireArguments().getBoolean("param"); |
| </code> |
| |
| =====Bouton back===== |
| |
| ====Appel manuel==== |
| |
| <code java> |
| mainActivity.getSupportFragmentManager().popBackStack(); |
| </code> |
| |
| ====Changement de fragment==== |
| |
| Le comportement du bouton back se définit dans le ''FragmentManager'' au moment du chargement du nouveau fragment. |
| |
| <code java> |
| fragmentManager.beginTransaction()... |
| .addToBackStack(null) |
| .commit(); |
| </code> |
| |
| 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 : |
| |
| <code java> |
| getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) { |
| @Override |
| public void handleOnBackPressed() { |
| // Back is pressed... Finishing the activity |
| finish(); |
| } |
| }); |
| </code> |
| |
| [[https://stackoverflow.com/questions/72634225/onbackpressed-is-deprecated-what-is-the-alternative|onBackPressed() is deprecated. What is the alternative?]] {{ :lang:android:fragment:android_-_onbackpressed_is_deprecated._what_is_the_alternative_-_stack_overflow_23_08_2023_09_36_51_.html |Archive du 27/07/2023 le 23/08/2023}} |
| |
| =====Binding===== |
| |
| Il existe ''View binding'' et ''Data binding''. |
| |
| Si l'objectif est seulement de remplacer les ''findViewById'', il faut utiliser ''View binding'' car plus léger. |
| |
| Si l'objectif est également de maîtriser les données lors de la reconstruction d'un fragment, ''Data binding'' est nécessaire. |
| |
| ====View binding==== |
| |
| ====Data binding==== |
| |
| * Chargement du fragment |
| |
| <code java> |
| @Override |
| @Nullable |
| public View onCreateView(@NonNull final LayoutInflater inflater, |
| @Nullable final ViewGroup container, @Nullable final Bundle savedInstanceState) { |
| super.onCreateView(inflater, container, savedInstanceState); |
| |
| binding = NameFragmentBinding.inflate(inflater, container, false); |
| binding.setLifecycleOwner(getViewLifecycleOwner()); // Uniquement nécessaire si le binding est lié à un LiveData. |
| |
| return binding.getRoot(); |
| } |
| </code> |
| |
| [[https://stackoverflow.com/questions/63336247/must-i-set-lifecycleowner-for-a-data-binding-in-android-studio)|Must I set lifecycleOwner for a data binding in Android Studio?]] {{ :lang:android:fragment:must_i_set_lifecycleowner_for_a_data_binding_in_android_studio_-_stack_overflow_23_08_2023_12_07_42_.html |Archive du 10/08/2020 le 23/08/2023}} |
| |
| [[https://developer.android.com/topic/libraries/data-binding/architecture|Bind layout views to Architecture Components]] {{ :lang:android:fragment:bind_layout_views_to_architecture_components_android_developers_23_08_2023_12_06_13_.html |Archive du 12/07/2023 le 23/08/2023}} |
| |
| * Utilisation des LiveData |
| |
| [[https://medium.com/swlh/basic-form-validation-in-android-with-live-data-and-data-binding-cb6b1d073717|Basic Form Validation in Android with Live Data and Data Binding]] {{ :lang:android:fragment:basic_form_validation_in_android_with_live_data_and_data_binding_by_brandon_wever_the_startup_medium_23_08_2023_12_12_03_.html |Archive du 07/10/2019 le 23/08/2023}} |
| |
| ====Problèmes===== |
| |
| Si une ressource ne génère pas le binding, il faut entourer la ressource par ''<layout></layout>''. |