Bağımlılıkları olan ViewModel'ler oluşturma Android Jetpack'in bir parçasıdır.

Bağımlılık yerleştirme en iyi uygulamaları doğrultusunda ViewModels, bağımlılıkları kurucularında parametre olarak kabul eder. Bunlar çoğu zaman alan veya veri katmanlarından kaldırabilirsiniz. Çünkü bu çerçeve ViewModelleri'nin örneklerini oluşturmak için özel bir mekanizma gerekir. O mekanizma ViewModelProvider.Factory arayüzüdür. Yalnızca uygulamalar ViewModelleri doğru kapsamda örneklenebilir.

CreationExtras içeren ViewModeller

ViewModel sınıfı kurucusuna bağımlılık içeriyorsa bir fabrika sağlayın ViewModelProvider.Factory arayüzünü uygular. Geçersiz kıl create(Class<T>, CreationExtras) işlevini kullanarak yeni bir ViewModel'i belirtir.

CreationExtras, size yardımcı olacak alakalı bilgilere ulaşmanızı sağlar bir ViewModel örneklendirir. Ekstralardan erişilebilen anahtarların listesi:

Anahtar Uygulama işlevi
ViewModelProvider.NewInstanceFactory.VIEW_MODEL_KEY ViewModelProvider.get() hizmetine aktardığınız özel anahtara erişim sağlar.
ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY Application sınıfının örneğine erişim sağlar.
SavedStateHandleSupport.DEFAULT_ARGS_KEY SavedStateHandle öğesini oluşturmak için kullanmanız gereken bağımsız değişken paketine erişim sağlar.
SavedStateHandleSupport.SAVED_STATE_REGISTRY_OWNER_KEY ViewModel öğesini oluşturmak için kullanılan SavedStateRegistryOwner öğesine erişim sağlar.
SavedStateHandleSupport.VIEW_MODEL_STORE_OWNER_KEY ViewModel öğesini oluşturmak için kullanılan ViewModelStoreOwner öğesine erişim sağlar.

Yeni bir SavedStateHandle örneği oluşturmak için şunu kullanın: CreationExtras.createSavedStateHandle().createSavedStateHandle()) aracı fonksiyonuna geçirmeniz ve bunu ViewModel'e iletmeniz gerekir.

Aşağıdaki, Application sınıfını kapsayan bir depo alır ve Bağımlılık olarak SavedStateHandle:

Kotlin

    import androidx.lifecycle.SavedStateHandle
    import androidx.lifecycle.ViewModel
    import androidx.lifecycle.ViewModelProvider
    import androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory.Companion.APPLICATION_KEY
    import androidx.lifecycle.createSavedStateHandle
    import androidx.lifecycle.viewmodel.CreationExtras

    class MyViewModel(
        private val myRepository: MyRepository,
        private val savedStateHandle: SavedStateHandle
    ) : ViewModel() {

        // ViewModel logic
        // ...

        // Define ViewModel factory in a companion object
        companion object {

            val Factory: ViewModelProvider.Factory = object : ViewModelProvider.Factory {
                @Suppress("UNCHECKED_CAST")
                override fun <T : ViewModel> create(
                    modelClass: Class<T>,
                    extras: CreationExtras
                ): T {
                    // Get the Application object from extras
                    val application = checkNotNull(extras[APPLICATION_KEY])
                    // Create a SavedStateHandle for this ViewModel from extras
                    val savedStateHandle = extras.createSavedStateHandle()

                    return MyViewModel(
                        (application as MyApplication).myRepository,
                        savedStateHandle
                    ) as T
                }
            }
        }
    }

Java

import static androidx.lifecycle.SavedStateHandleSupport.createSavedStateHandle;
import static androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY;

import androidx.lifecycle.SavedStateHandle;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.viewmodel.ViewModelInitializer;

public class MyViewModel extends ViewModel {

    public MyViewModel(
        MyRepository myRepository,
        SavedStateHandle savedStateHandle
    ) { /* Init ViewModel here */ }

    static final ViewModelInitializer<MyViewModel> initializer = new ViewModelInitializer<>(
        MyViewModel.class,
        creationExtras -> {
            MyApplication app = (MyApplication) creationExtras.get(APPLICATION_KEY);
            assert app != null;
            SavedStateHandle savedStateHandle = createSavedStateHandle(creationExtras);

            return new MyViewModel(app.getMyRepository(), savedStateHandle);
        }
    );
}

Daha sonra, ViewModel'in bir örneğini alırken bu fabrikayı kullanabilirsiniz:

Kotlin

import androidx.activity.viewModels

class MyActivity : AppCompatActivity() {

    private val viewModel: MyViewModel by viewModels { MyViewModel.Factory }

    // Rest of Activity code
}

Java

import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.ViewModelProvider;

public class MyActivity extends AppCompatActivity {

MyViewModel myViewModel = new ViewModelProvider(
    this,
    ViewModelProvider.Factory.from(MyViewModel.initializer)
).get(MyViewModel.class);

// Rest of Activity code
} 

Jetpack Compose

import androidx.lifecycle.viewmodel.compose.viewModel

@Composable
fun MyScreen(
    modifier: Modifier = Modifier,
    viewModel: MyViewModel = viewModel(factory = MyViewModel.Factory)
) {
    // ...
}

Alternatif olarak, fabrikalar oluşturmak için ViewModel fabrika DSL'sini deyimsel Kotlin API'si:

import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory.Companion.APPLICATION_KEY
import androidx.lifecycle.createSavedStateHandle
import androidx.lifecycle.viewmodel.initializer
import androidx.lifecycle.viewmodel.viewModelFactory

class MyViewModel(
    private val myRepository: MyRepository,
    private val savedStateHandle: SavedStateHandle
) : ViewModel() {
    // ViewModel logic

    // Define ViewModel factory in a companion object
    companion object {
        val Factory: ViewModelProvider.Factory = viewModelFactory {
            initializer {
                val savedStateHandle = createSavedStateHandle()
                val myRepository = (this[APPLICATION_KEY] as MyApplication).myRepository
                MyViewModel(
                    myRepository = myRepository,
                    savedStateHandle = savedStateHandle
                )
            }
        }
    }
}

2.5.0'dan daha eski ViewModel sürümü için fabrikalar

ViewModel'in 2.5.0'dan eski bir sürümünü kullanıyorsanız ViewModelProvider.Factory alanını genişleten sınıfların bir alt kümesinden fabrikalar ve create(Class<T>) işlevini uygulayın. Hangi bağımlılıklara ViewModel'in gerektirdiği şekilde, aşağıdakilerden farklı bir sınıfın genişletilmesi gerekir:

Application veya SavedStateHandle gerekli değilse ViewModelProvider.Factory.

Aşağıdaki örnekte, bir hedef URL için AbstractSavedStateViewModelFactory Aşağıdaki örnekte depo olarak bir depo ve SavedStateHandle türünü alan ViewModel bağımlılık:

Kotlin

class MyViewModel(
private val myRepository: MyRepository,
private val savedStateHandle: SavedStateHandle
) : ViewModel() {

// ViewModel logic ...

// Define ViewModel factory in a companion object
companion object {
    fun provideFactory(
        myRepository: MyRepository,
        owner: SavedStateRegistryOwner,
        defaultArgs: Bundle? = null,
    ): AbstractSavedStateViewModelFactory =
        object : AbstractSavedStateViewModelFactory(owner, defaultArgs) {
            @Suppress("UNCHECKED_CAST")
            override fun <T : ViewModel> create(
                key: String,
                modelClass: Class<T>,
                handle: SavedStateHandle
            ): T {
                return MyViewModel(myRepository, handle) as T
            }
        }
    }
}

Java

import androidx.annotation.NonNull;
import androidx.lifecycle.AbstractSavedStateViewModelFactory;
import androidx.lifecycle.SavedStateHandle;
import androidx.lifecycle.ViewModel;

public class MyViewModel extends ViewModel {
    public MyViewModel(
        MyRepository myRepository,
        SavedStateHandle savedStateHandle
    ) { /* Init ViewModel here */ }
}

public class MyViewModelFactory extends AbstractSavedStateViewModelFactory {

    private final MyRepository myRepository;

    public MyViewModelFactory(
        MyRepository myRepository
    ) {
        this.myRepository = myRepository;
    }

    @SuppressWarnings("unchecked")
    @NonNull
    @Override
    protected <T extends ViewModel> T create(
        @NonNull String key, @NonNull Class<T> modelClass, @NonNull SavedStateHandle handle
    ) {
        return (T) new MyViewModel(myRepository, handle);
    }
}

Daha sonra, ViewModel'inizi almak için fabrikayı kullanabilirsiniz:

Kotlin

import androidx.activity.viewModels

class MyActivity : AppCompatActivity() {

    private val viewModel: MyViewModel by viewModels {
        MyViewModel.provideFactory((application as MyApplication).myRepository, this)
    }

    // Rest of Activity code
}

Java

import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.ViewModelProvider;

public class MyActivity extends AppCompatActivity {

    MyViewModel myViewModel = new ViewModelProvider(
        this,
        ViewModelProvider.Factory.from(MyViewModel.initializer)
    ).get(MyViewModel.class);

    // Rest of Activity code
}

Jetpack Compose

import androidx.lifecycle.viewmodel.compose.viewModel

@Composable
fun MyScreen(
    modifier: Modifier = Modifier,
    viewModel: MyViewModel = viewModel(
        factory = MyViewModel.provideFactory(
            (LocalContext.current.applicationContext as MyApplication).myRepository,
            owner = LocalSavedStateRegistryOwner.current
        )
    )
) {
    // ...
}
ziyaret edin.