Présentation de ViewModel (Vues)
Concepts et implémentation de Jetpack Compose
La classe ViewModel est une logique métier ou un conteneur d'état au niveau de l'écran
holder. Elle expose l'état au niveau de l'UI et encapsule la logique métier associée.
Son principal avantage est qu'elle assure la mise en cache et la persistance de l'état en cas de modification de la configuration. Cela signifie que votre interface utilisateur n'a pas besoin de récupérer à nouveau les données lorsque vous passez d'une activité à une autre ou suite à une modification de la configuration, par exemple en cas de rotation de l'écran.
Avantages de ViewModel
L'alternative à un ViewModel est une classe simple qui contient les données que vous affichez dans l'interface utilisateur. Cette méthode peut s'avérer problématique lors du passage d'une activité ou d'une destination de navigation à une autre. Elle détruit ces données si vous ne les stockez pas au moyen du mécanisme d'enregistrement de l'état de l'instance. ViewModel fournit une API pratique pour assurer la persistance des données qui résout ce problème.
La classe ViewModel présente principalement deux avantages :
- Elle vous permet de conserver l'état de l'UI.
- Elle donne accès à la logique métier.
Champ d'application
Lorsque vous instanciez un ViewModel, vous lui transmettez un objet qui implémente l'interface ViewModelStoreOwner. Il peut s'agir d'une destination ou d'un graphique de navigation, d'une activité, d'un fragment, ou de tout autre type qui implémente l'interface. Votre ViewModel s'applique ensuite au Lifecycle du
ViewModelStoreOwner. Il reste en mémoire jusqu'à ce que son ViewModelStoreOwner disparaisse définitivement.
Une plage de classes représente soit des sous-classes directes, soit des sous-classes indirectes de l'interface ViewModelStoreOwner. Les sous-classes directes sont ComponentActivity, Fragment et NavBackStackEntry.
Pour obtenir la liste complète des sous-classes indirectes, consultez la
ViewModelStoreOwner documentation de référence.
Implémenter un ViewModel
Voici un exemple d'implémentation d'un ViewModel pour un écran permettant à l'utilisateur de lancer des dés.
Kotlin
data class DiceUiState(
val firstDieValue: Int? = null,
val secondDieValue: Int? = null,
val numberOfRolls: Int = 0,
)
class DiceRollViewModel : ViewModel() {
// Expose screen UI state
private val _uiState = MutableStateFlow(DiceUiState())
val uiState: StateFlow<DiceUiState> = _uiState.asStateFlow()
// Handle business logic
fun rollDice() {
_uiState.update { currentState ->
currentState.copy(
firstDieValue = Random.nextInt(from = 1, until = 7),
secondDieValue = Random.nextInt(from = 1, until = 7),
numberOfRolls = currentState.numberOfRolls + 1,
)
}
}
}
Java
public class DiceUiState {
private final Integer firstDieValue;
private final Integer secondDieValue;
private final int numberOfRolls;
// ...
}
public class DiceRollViewModel extends ViewModel {
private final MutableLiveData<DiceUiState> uiState =
new MutableLiveData(new DiceUiState(null, null, 0));
public LiveData<DiceUiState> getUiState() {
return uiState;
}
public void rollDice() {
Random random = new Random();
uiState.setValue(
new DiceUiState(
random.nextInt(7) + 1,
random.nextInt(7) + 1,
uiState.getValue().getNumberOfRolls() + 1
)
);
}
}
Vous pouvez ensuite accéder au ViewModel à partir d'une activité comme suit :
Kotlin
import androidx.activity.viewModels
class DiceRollActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
// Create a ViewModel the first time the system calls an activity's onCreate() method.
// Re-created activities receive the same DiceRollViewModel instance created by the first activity.
// Use the 'by viewModels()' Kotlin property delegate
// from the activity-ktx artifact
val viewModel: DiceRollViewModel by viewModels()
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.uiState.collect {
// Update UI elements
}
}
}
}
}
Java
public class MyActivity extends AppCompatActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Create a ViewModel the first time the system calls an activity's onCreate() method.
// Re-created activities receive the same MyViewModel instance created by the first activity.
DiceRollViewModel model = new ViewModelProvider(this).get(DiceRollViewModel.class);
model.getUiState().observe(this, uiState -> {
// update UI
});
}
}
Recommandations personnalisées
- Remarque : Le texte du lien s'affiche lorsque JavaScript est désactivé
- Utiliser des coroutines Kotlin avec des composants tenant compte du cycle de vie
- Enregistrer les états de l'interface utilisateur
- Charger et afficher des données paginées