ViewModel'e genel bakış (Görünümler)

Kavramlar ve Jetpack Compose uygulaması

ViewModel sınıfı, iş mantığı veya ekran düzeyinde durum tutucudur. Durumu kullanıcı arayüzüne sunar ve ilgili iş mantığını kapsar. Başlıca avantajı, durumu önbelleğe alması ve yapılandırma değişiklikleri boyunca kalıcı hale getirmesidir. Bu sayede, etkinlikler arasında gezinirken veya ekranı döndürme gibi yapılandırma değişikliklerinden sonra kullanıcı arayüzünüzün verileri tekrar getirmesi gerekmez.

ViewModel'in avantajları

ViewModel'e alternatif olarak, kullanıcı arayüzünüzde gösterdiğiniz verileri tutan düz bir sınıf kullanabilirsiniz. Bu durum, etkinlikler veya gezinme hedefleri arasında gezinirken sorun yaratabilir. Bu işlemi yaparsanız kaydedilmiş örnek durumu mekanizmasını kullanarak depolamadığınız veriler yok edilir. ViewModel, bu sorunu çözen veri kalıcılığı için uygun bir API sağlar.

ViewModel sınıfının temel avantajları esasen iki tanedir:

  • Kullanıcı arayüzü durumunu kalıcı hale getirmenizi sağlar.
  • İş mantığına erişim sağlar.

Kapsam

ViewModel'i örneklediğinizde, ViewModelStoreOwner arayüzünü uygulayan bir nesne iletirsiniz. Bu, bir gezinme hedefi, gezinme grafiği, etkinlik, parça veya arayüzü uygulayan başka bir tür olabilir. ViewModel'ınız daha sonra ViewModelStoreOwner öğesinin Lifecycle kapsamına alınır. Bu hata, ViewModelStoreOwner kalıcı olarak ortadan kalkana kadar bellekte kalır.

Bir dizi sınıf, ViewModelStoreOwner arayüzünün doğrudan veya dolaylı alt sınıflarıdır. Doğrudan alt sınıflar ComponentActivity, Fragment ve NavBackStackEntry'dır. Dolaylı alt sınıfların tam listesi için ViewModelStoreOwner referansına bakın.

ViewModel'i uygulama

Aşağıda, kullanıcının zar atmasına olanak tanıyan bir ekran için ViewModel'in örnek bir uygulaması verilmiştir.

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
            )
        );
    }
}

Ardından, ViewModel'e bir etkinlikten aşağıdaki gibi erişebilirsiniz:

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
        });
    }
}