Visão geral do ViewModel (Views)
Conceitos e implementação do Jetpack Compose
A classe ViewModel é um detentor de estado da tela ou da lógica de
negócios. Ele expõe o estado à interface e encapsula a lógica de negócios correspondente.
A principal vantagem do ViewModel é que ele armazena o estado em cache e mantém essas informações mesmo
após mudanças de configuração. Isso significa que a interface não precisa buscar dados novamente
ao navegar entre diferentes atividades ou implementar mudanças de configuração, como
ao girar a tela.
Benefícios do ViewModel
Uma alternativa para o uso de ViewModel é implementar uma classe simples contendo os dados mostrados na interface. Isso pode se tornar um problema ao navegar entre diferentes atividades ou destinos de navegação. Isso destrói esses dados se você não os armazenar usando o mecanismo de estado de instância salva. O ViewModel fornece uma API adequada para a persistência de dados que resolve esse problema.
Os principais benefícios da classe ViewModel são essencialmente dois:
- Ele permite manter o estado da interface.
- Oferece acesso à lógica de negócios.
Escopo
Ao instanciar um ViewModel, o sistema transmite um objeto que implementa a interface
ViewModelStoreOwner. Esse objeto pode ser um destino ou
um gráfico de navegação, uma atividade, um fragmento ou qualquer outro tipo que implemente a
interface. Em seguida, o Lifecycle do
ViewModelStoreOwner é definido como o escopo do ViewModel. Ele continua na memória até que o ViewModelStoreOwner
apareça de forma definitiva.
Um intervalo de classes é uma subclasse direta ou indireta da
interface ViewModelStoreOwner. As subclasses diretas são
ComponentActivity, Fragment e NavBackStackEntry.
Para uma lista completa de subclasses indiretas, consulte a
documentação de referência do ViewModelStoreOwner.
Implementar um ViewModel
Confira abaixo um exemplo de implementação de um ViewModel para uma tela que permite que o usuário jogue o dado.
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
)
);
}
}
Depois, você pode acessar o ViewModel de uma atividade desta maneira:
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
});
}
}
Recomendados para você
- Observação: o texto do link aparece quando o JavaScript está desativado.
- Usar corrotinas do Kotlin com componentes que reconhecem o ciclo de vida
- Salvar estados da interface
- Carregar e exibir dados paginados