ViewModel-Übersicht (Ansichten)
Konzepte und Jetpack Compose-Implementierung
Die ViewModel Klasse ist ein State Holder für die Geschäftslogik oder die Bildschirmebene. Sie stellt den Status für die Benutzeroberfläche bereit und kapselt die zugehörige Geschäftslogik.
Ihr Hauptvorteil besteht darin, dass sie den Status im Cache speichert und bei Konfigurationsänderungen beibehält. Das bedeutet, dass die Benutzeroberfläche beim Wechsel zwischen Aktivitäten oder nach Konfigurationsänderungen, z. B. beim Drehen des Bildschirms, keine Daten noch einmal abrufen muss.
Vorteile von ViewModels
Die Alternative zu einem ViewModel ist eine einfache Klasse, die die Daten enthält, die auf der Benutzeroberfläche angezeigt werden. Dies kann beim Wechsel zwischen Aktivitäten oder Navigationszielen zu Problemen führen. Dabei werden die Daten zerstört, wenn sie nicht mit dem Mechanismus für den gespeicherten Instanzstatus gespeichert werden. ViewModel bietet eine praktische API für die Datenpersistenz, mit der dieses Problem behoben wird.
Die wichtigsten Vorteile der ViewModel-Klasse sind:
- Sie ermöglicht es, den UI-Status beizubehalten.
- Sie bietet Zugriff auf die Geschäftslogik.
Umfang
Wenn Sie ein ViewModel instanziieren, übergeben Sie ihm ein Objekt, das die
ViewModelStoreOwner Schnittstelle implementiert. Dabei kann es sich um ein Navigationsziel, einen Navigationsgraphen, eine Aktivität, ein Fragment oder einen anderen Typ handeln, der die Schnittstelle implementiert. Ihr ViewModel ist dann auf den Lifecycle des
ViewModelStoreOwner beschränkt. Es bleibt im Arbeitsspeicher, bis der ViewModelStoreOwner endgültig entfernt wird.
Eine Reihe von Klassen sind direkte oder indirekte Unterklassen der Schnittstelle ViewModelStoreOwner. Die direkten Unterklassen sind
ComponentActivity, Fragment und NavBackStackEntry.
Eine vollständige Liste der indirekten Unterklassen finden Sie in der
ViewModelStoreOwner Referenz.
ViewModel implementieren
Im Folgenden finden Sie eine Beispielimplementierung eines ViewModels für einen Bildschirm, auf dem der Nutzer würfeln kann.
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
)
);
}
}
Sie können dann wie folgt auf das ViewModel aus einer Aktivität zugreifen:
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
});
}
}
Empfehlungen für Sie
- Hinweis: Linktext wird angezeigt, wenn JavaScript deaktiviert ist
- Kotlin-Coroutinen mit lebenszyklusbezogenen Komponenten verwenden
- UI-Status speichern
- Paginierte Daten laden und anzeigen