Els Fragment
ens permetran disposar de diverses Activity alhora en la mateixa pantalla, a mode de pestanyes. Podrem navegar amb una NavigationBar
que acostuma a tenir disposicions diferents segons la grandària i orientació de la pantalla, o del tipus de dispositiu.
Referències:
App amb fragments:
Bottom Navigation Activity
.Fragment
buit. Tria bé el nom (posarem d'exemple NewFragment
) Botó dret -> New -> Fragment -> Fragment (Blank)
Fragment
a la navegació (via XML):res -> navigation -> mobile_navigation.xml
Fragment
al menú de la NavigationBar
:res -> menu -> bottom_nav_menu.xml
MainActivity.java
i afegir R.id.navigation_XXX
al onCreate
:AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder( R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_notifications, R.id.navigation_XXX) .build();
ActivityMain
i sol deixar buida la part de dalt. Podeu mirar aquest post per eliminar-la (simplement eliminant el padding o posar-lo a 0).
Haureu vist que el NewFragment
té només 1 sol arxiu, mentre que els Fragment
creats a la plantilla (Home, Dashboard i Notifications) en tenen 2. Això és degut a que, acompanyant el Fragment
, també tenim un ViewModel
. Aquest objecte ViewModel
ens serveix per facilitar la persistència dels canvis en el GUI sense haver d'utilitzar accés a fitxers o altres sistemes d'emmagatzemament.
No és necessari utilitzar el ViewModel
, tot i que pot facilitar molta gestió, com per exemple quan girem (rotate) el mòbil de format portrait a landscape, moment en el qual es destrueixen les views i es tornen a crear de nou amb les noves mides i, per tant, perdem les dades del GUI.
Un ViewModel ens permetrà connectar la View amb el ViewModel mitjançant la sentència observe
, que prové d'un patró de disseny Observer. Aquest és el codi que ve per defecte a la plantilla:
homeViewModel.getText().observe(getViewLifecycleOwner(), textView::setText);
Afegeix un Button
i un TextView
al HomeFragment
. Hauriem de tenir 2 TextView
, un AMB ViewModel (el què ja existia) i un sense.
Implementa aquesta funcionalitat simple: quan premem el botó, canvia el text dels dos TextView
, però cal fer-ho diferent en l'un i l'altre:
TextView
AMB ViewModel
cal modificar el ViewModel
.TextView
SENSE ViewModel
el modifiquem directament.Algo així:
homeButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // Modifiquem objecte sense ViewModel directament TextView directTextView = root.findViewById(R.id.directTextView); directTextView.setText("[NOT ViewModel] canvi de text"); // Modifiquem contingut ViewModel (es reflaxarà a la View) homeViewModel.setText("[WITH ViewModel] canvi de text"); } });
Ara posa l'app en marxa, habilita el autorotate de l'emulador i observa què passa.
Com expliques aquest comportament?