نمای کلی ViewModel (Views)

مفاهیم و پیاده‌سازی Jetpack Compose

کلاس ViewModel یک نگهدارنده‌ی وضعیت در سطح صفحه یا منطق کسب و کار است. این کلاس وضعیت را در اختیار رابط کاربری قرار می‌دهد و منطق کسب و کار مرتبط را کپسوله‌سازی می‌کند. مزیت اصلی آن این است که وضعیت را ذخیره کرده و آن را در طول تغییرات پیکربندی حفظ می‌کند. این بدان معناست که رابط کاربری شما هنگام پیمایش بین فعالیت‌ها یا دنبال کردن تغییرات پیکربندی، مانند هنگام چرخاندن صفحه، نیازی به واکشی مجدد داده‌ها ندارد.

مزایای ViewModel

جایگزین ViewModel، یک کلاس ساده است که داده‌هایی را که در رابط کاربری خود نمایش می‌دهید، در خود نگه می‌دارد. این می‌تواند هنگام پیمایش بین فعالیت‌ها یا مقاصد ناوبری مشکل‌ساز شود. اگر این کار را با استفاده از مکانیسم وضعیت نمونه ذخیره شده ذخیره نکنید، آن داده‌ها از بین می‌روند. ViewModel یک API مناسب برای ماندگاری داده‌ها ارائه می‌دهد که این مشکل را حل می‌کند.

مزایای کلیدی کلاس ViewModel اساساً دو مورد است:

  • به شما امکان می‌دهد حالت رابط کاربری (UI) را ثابت نگه دارید.
  • این امکان دسترسی به منطق کسب و کار را فراهم می‌کند.

دامنه

وقتی یک ViewModel را نمونه‌سازی می‌کنید، یک شیء به آن ارسال می‌کنید که رابط ViewModelStoreOwner پیاده‌سازی می‌کند. این شیء می‌تواند یک مقصد ناوبری (Navigation destination)، گراف ناوبری (Navigation graph)، فعالیت (activity)، قطعه کد (fragment) یا هر نوع دیگری باشد که رابط را پیاده‌سازی می‌کند. سپس 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,
            )
        }
    }
}

جاوا

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

جاوا

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
        });
    }
}
{% کلمه به کلمه %} {% فعل کمکی %} {% کلمه به کلمه %} {% فعل کمکی %}