Bağımlılıklarla (Görünümler) ViewModel'ler oluşturma Android Jetpack'in bir parçasıdır.
Kavramlar ve Jetpack Compose uygulaması
Bağımlılık ekleme ile ilgili en iyi uygulamalara uygun olarak, ViewModel'ler oluşturucularında bağımlılıkları parametre olarak alabilir. Bunlar çoğunlukla alan veya veri katmanlarındaki türlerdir. Çerçeve ViewModels'i sağladığından bunların örneklerini oluşturmak için özel bir mekanizma gerekir. Bu mekanizma ViewModelProvider.Factory arayüzüdür. Bu arayüzün yalnızca uygulamaları, ViewModels'i doğru kapsamda oluşturabilir.
CreationExtras ile ViewModels
Bir ViewModel sınıfının oluşturucusunda bağımlılıklar varsa ViewModelProvider.Factory arayüzünü uygulayan bir fabrika sağlayın.
ViewModel'in yeni bir örneğini sağlamak için create(Class<T>, CreationExtras) işlevini geçersiz kılın.
APPLICATION_KEY ile CreationExtras
Aşağıda, ViewModel sınıfı kapsamlı bir repository ve SavedStateHandle bağımlılıklarını alan bir ViewModel örneğinin nasıl sağlanacağına dair bir örnek verilmiştir:Application
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);
}
);
}
Ardından, ViewModel ö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
}
Özel parametreleri CreationExtras olarak iletme
Özel bir anahtar oluşturarak ViewModel aracılığıyla CreationExtras öğenize bağımlılıklar iletebilirsiniz.
Bu, ViewModel öğenizin Application sınıfı ve APPLICATION_KEY üzerinden erişilemeyen nesnelere bağlı olduğu durumlarda faydalı olabilir. Bunun bir örneği, ViewModel öğenizin Kotlin Multiplatform modülünde oluşturulması ve bu nedenle Android bağımlılıklarına erişememesidir.
Bu örnekte ViewModel, özel bir anahtar tanımlar ve bunu ViewModelProvider.Factory içinde kullanır.
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.CreationExtras
import androidx.lifecycle.viewmodel.initializer
import androidx.lifecycle.viewmodel.viewModelFactory
class MyViewModel(
private val myRepository: MyRepository,
) : ViewModel() {
// ViewModel logic
// Define ViewModel factory in a companion object
companion object {
// Define a custom key for your dependency
val MY_REPOSITORY_KEY = object : CreationExtras.Key<MyRepository> {}
val Factory: ViewModelProvider.Factory = viewModelFactory {
initializer {
// Get the dependency in your factory
val myRepository = this[MY_REPOSITORY_KEY] as MyRepository
MyViewModel(
myRepository = myRepository,
)
}
}
}
}
ViewModel'yi ComponentActivity, Fragment veya NavBackStackEntry gibi bir ViewModelStoreOwner'den CreationExtras.Key ile örneklendirebilirsiniz.
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelStoreOwner
import androidx.lifecycle.viewmodel.CreationExtras
import androidx.lifecycle.viewmodel.MutableCreationExtras
// ...
// Use from ComponentActivity, Fragment, NavBackStackEntry,
// or another ViewModelStoreOwner.
val viewModelStoreOwner: ViewModelStoreOwner = this
val myViewModel: MyViewModel = ViewModelProvider.create(
viewModelStoreOwner,
factory = MyViewModel.Factory,
extras = MutableCreationExtras().apply {
set(MyViewModel.MY_REPOSITORY_KEY, myRepository)
},
)[MyViewModel::class]
ViewModel'in 2.5.0'dan eski sürümleri için fabrikalar
ViewModel'nın 2.5.0'dan eski bir sürümünü kullanıyorsanız ViewModelProvider.Factory'ı genişleten ve create(Class<T>) işlevini uygulayan bir sınıf alt kümesinden fabrikalar sağlamanız gerekir. ViewModel öğesinin ihtiyaç duyduğu bağımlılıklara bağlı olarak, farklı bir sınıfın genişletilmesi gerekir:
Applicationsınıfı gerekiyorsaAndroidViewModelFactory.SavedStateHandlebağımlılık olarak iletilmesi gerekiyorsaAbstractSavedStateViewModelFactory.
Application veya SavedStateHandle gerekmiyorsa ViewModelProvider.Factory'den uzatmanız yeterlidir.
Aşağıdaki örnekte, bağımlılık olarak bir depo ve SavedStateHandle türü alan bir ViewModel için AbstractSavedStateViewModelFactory kullanılmaktadır:
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);
}
}
Ardından, ViewModel'inizi almak için factory'yi 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
}
Sizin için önerilenler
- Not: JavaScript kapalıyken bağlantı metni gösterilir.
- ViewModel için Saved State modülü
- Kullanıcı arayüzü durumlarını kaydetme
- LiveData'ya genel bakış