Обзор ViewModel (представлений)
Концепции и реализация Jetpack Compose
Класс ViewModel — это хранилище бизнес-логики или состояния на уровне экрана . Он предоставляет доступ к состоянию пользовательскому интерфейсу и инкапсулирует связанную с ним бизнес-логику. Его главное преимущество заключается в том, что он кэширует состояние и сохраняет его при изменении конфигурации. Это означает, что вашему пользовательскому интерфейсу не нужно повторно получать данные при переходе между активностями или при изменении конфигурации, например, при повороте экрана.
Преимущества ViewModel
Альтернативой ViewModel является обычный класс, хранящий данные, отображаемые в пользовательском интерфейсе. Это может стать проблемой при навигации между активностями или пунктами навигации. В этом случае данные уничтожаются, если не использовать механизм сохранения состояния экземпляра . ViewModel предоставляет удобный API для сохранения данных, который решает эту проблему.
Основные преимущества класса ViewModel заключаются, по сути, в двух:
- Это позволяет сохранять состояние пользовательского интерфейса.
- Это обеспечивает доступ к бизнес-логике.
Объем
При создании экземпляра ViewModel вы передаете ему объект, реализующий интерфейс ViewModelStoreOwner . Это может быть навигационный объект, навигационный граф, активность, фрагмент или любой другой тип, реализующий этот интерфейс. Ваш ViewModel затем ограничивается Lifecycle ViewModelStoreOwner . Он остается в памяти до тех пор, пока его ViewModelStoreOwner не будет удален навсегда.
Ряд классов являются прямыми или косвенными подклассами интерфейса ViewModelStoreOwner . Прямыми подклассами являются ComponentActivity , Fragment и NavBackStackEntry . Полный список косвенных подклассов см. в справочнике ViewModelStoreOwner .
Реализуйте ViewModel.
Ниже приведён пример реализации ViewModel для экрана, позволяющего пользователю бросать игральные кости.
Котлин
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
)
);
}
}
Затем вы можете получить доступ к ViewModel из активности следующим образом:
Котлин
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
});
}
}
Рекомендуем вам
- Примечание: текст ссылки отображается, когда JavaScript отключен.
- Используйте сопрограммы Kotlin с компонентами, учитывающими жизненный цикл.
- Сохранение состояний пользовательского интерфейса
- Загрузка и отображение постраничных данных