Selon la section "Partager des données entre fragments" sur https://developer.android.com/topic/libraries/architecture/viewmodel, on nous dit que créer un ViewModel dans la portée de l'activité et le partager parmi les fragments est la voie à suivre .
C'est le fragment qui définit la valeur dans le ViewModel
class SharedViewModel : ViewModel() { val selected = MutableLiveData<Item>() fun select(item: Item) { selected.value = item } }
C'est le fragment de détail qui utilise le jeu de propriétés
class DetailFragment : Fragment() { private lateinit var model: SharedViewModel override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) model = activity?.run { ViewModelProviders.of(this).get(SharedViewModel::class.java) } ?: throw Exception("Invalid Activity") model.selected.observe(this, Observer<Item> { item -> // Update the UI }) } }
Ceci est le ViewModel
class MasterFragment : Fragment() { private lateinit var itemSelector: Selector private lateinit var model: SharedViewModel override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) model = activity?.run { ViewModelProviders.of(this).get(SharedViewModel::class.java) } ?: throw Exception("Invalid Activity") itemSelector.setOnClickListener { item -> // Update the UI } } }
Ma question est simple. En supposant que MasterFragment définisse une valeur dans le ViewModel sur un clic de bouton, comment pourrions-nous récupérer cette valeur en y accédant APRÈS QUE LE SYSTÈME A TUÉ NOTRE APPLICATION ET LA RESTAURÉ?.
Notre DetailFragment ne verra pas la valeur puisque nous l'avons défini sur le bouton cliquez dans le MasterFragment. Pour mieux comprendre la question, considérons que nous avons les fragments A, B, C et D et qu'ils partagent un ViewModel qui a une valeur Fragment AB et C ensemble calculée et placée dans ViewModel pour que le fragment D y accède.
Désormais, lorsque le système tue et recrée notre application, le fragment D n'aura plus cette valeur disponible.
OnSaveInstance ne sera pas non plus en mesure d'aider beaucoup sans recourir à du code sale. Pour les situations simples, oui, mais comme celle dans laquelle FragmentA B et C ensemble font une valeur, dans cette situation, OnSaveInstance serait problématique.
OnSaveInstance aurait dû être à l'intérieur du ViewModel mais hélas je ne pense pas que ce soit le cas. Des idées?
3 Réponses :
Si vous souhaitez toujours obtenir la valeur stockée après la réinitialisation ou la suppression de l'application, vous devez enregistrer les données dans SharedPreferences ou la base de données SqLite interne et la restaurer après le démarrage de l'application.
"SharedPreferences ou base de données interne SqLite" Vous êtes également autorisé à le sauvegarder en utilisant d'autres méthodes. Vous n'avez pas besoin d'utiliser l'un de ces deux
oui, il y a plus de méthodes, mais ce sont les principales et les meilleures pratiques
you need to save data to
La raison you need to save data to
laquelle j'ai fait le commentaire est que vous avez utilisé le mot «besoin». Vous n'avez pas BESOIN d'utiliser ces méthodes.
Les objets ViewModel sont étendus au cycle de vie transmis au ViewModelProvider lors de l'obtention du ViewModel. Le ViewModel reste en mémoire jusqu'à ce que le cycle de vie auquel il est destiné disparaisse définitivement: dans le cas d'une activité, quand il se termine, tandis que dans le cas d'un fragment, quand il est détaché.
Ma question est simple. En supposant que MasterFragment définisse une valeur dans le ViewModel sur un buttonClick, comment pourrions-nous récupérer cette valeur en y accédant APRÈS QUE LE SYSTÈME A TUÉ NOTRE APPLICATION ET LA RESTART?.
Vous ne pouvez pas récupérer la valeur si l'application est supprimée par l'utilisateur ou le système ou redémarrée.
Pour résoudre votre objectif d'accumuler les données des activités A, B et C et de les afficher dans l'activité D même si l'application est arrêtée ou redémarrée, vous pouvez choisir une méthode parmi les suivantes:
1. SharedPreference
2. Salle de base de données locale ou SQLite
3. Stockez les données dans un fichier
Je vous recommande d'utiliser SharedPreference pour les petites données et Room for Large and Complex data.
En un mot, ViewModel stocke les données temporairement pour survivre au changement d'orientation (pas besoin d'écrire du code de onSaveInstanceState
et onRestoreInstanceState
) et de partager des données entre les activités et les fragments. Les données seront perdues si l'activité est détruite ou si le fragment est détaché.
Pour ceux qui utilisent Kotlin, essayez l'approche suivante:
Ajoutez les bibliothèques androidx ViewModel et LiveData à votre fichier gradle
Appelez votre viewmodel à l'intérieur du fragment comme ceci:
class MainFragment : Fragment() { private lateinit var viewModel: ViewModel override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) // kotlin does not have a getActivity() built in method instead we use activity, which is null-safe activity?.let { viemModel = ViewModelProvider(it).get(SharedViewModel::class.java) } } }