Android

ViewModel veya AndroidViewModel Oluşturmanın Önerilen Yolları

oluşturmanın birkaç yolu var ViewModel ve AndroidViewModel. Bu makale, bunları oluşturmanın Kotlin örneklerini gösterir.

Bu bir örnek ViewModel veya AndroidViewModel sahip olabileceğiniz sınıf.

class MyViewModel: ViewModel() {
}
class MyAndroidViewModel (app: Application)
    : AndroidViewModel(app) {
}

Buradaki kod örnekleri, parça sınıfında kullanılmaktadır. Bu yüzden aktivite sınıfında çalışmayabilir. Bunları kopyalayıp aktivite sınıfınıza yapıştırırsanız küçük değişiklikler gerekir.

Kotlin’e aşina değilseniz, bazı hızlı örnekleri inceleyebilirsiniz. burada önce “Delegasyon” gibi bazı önemli kavramları anlamak.

Manuel Oluşturma – Bunu yapmayın!

private val viewModel = MyViewModel()
private val androidViewModel = 
    MyAndroidViewModel(requireActivity().application)

Bu, yalnızca telefonunuzu döndürmezseniz çalışır. Telefonunuzu döndürdüğünüzde, bir etkinlik veya parça yok edilir ve yeniden oluşturulur. Yeni bir örneği ViewModel veya AndroidViewModel tekrar oluşturulur. Böylece ekran döndürmeden önceki tüm veriler kaybolur. Bu amacı bozar ViewModel mimari. İstediğiniz ViewModel aktivite veya parça imha yoluyla hayatta kalmak için.

Kullanma sebebini anlamadığım için bu hatayı yaptım.ViewModelProvider yaratmak ViewModel

ViewModelProvider ile lateinit var

private lateinit var viewModel: MyViewModel
private lateinit var androidViewModel: MyAndroidViewModel
override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View {

    viewModel = ViewModelProvider(this).get(MyViewModel::class.java)
    androidViewModel =          
        ViewModelProvider(this).get(MyAndroidViewModel::class.java)
}

kullanma ViewModelProvider yaratmanın doğru yolu ViewModel. Etkinlik veya parça oluşturulduğunda, ViewModelProvider ilk yaratılanı yeniden kullanmayı anlayacak kadar akıllı ViewModel misal.

Eğer ViewModel kullanarak değişmez (ki bu muhtemelen doğrudur), val Kotlin değişkeni burada daha iyi bir seçenektir.

ViewModelProvider ile tembelce

Kullanmak val değişken, kullandığınız by lazy özellik başlatma. Temsilci blok, değişkene ilk erişildiğinde yürütülür.

private val viewModel: MyViewModel by lazy {
    ViewModelProvider(this).get(MyViewModel::class.java)
}

private val androidViewModel: MyAndroidViewModel by lazy {
    ViewModelProvider(this).get(MyAndroidViewModel::class.java)
}

Kod şundan çok daha temiz görünüyor lateinit var çözüm. Ancak, başka bir zarif yol kullanmaktır. by viewModels veya by activityViewModels.

viewModels / aktiviteViewModels tarafından

Bu Özellik Temsilcisini kullanmak için build.gradle’a (modül düzeyi) aşağıdaki bağımlılığın eklenmesi gerekir. Sürüm sadece bir örnektir, daha sonraki veya en son sürümü kullanabilirsiniz.

implementation 'androidx.fragment:fragment-ktx:1.3.6'

Aşağıdaki kod harika! Esasen aynı şeyi yapar by lazy belirtmeye gerek kalmadan ViewModelProvider. Bunu sizin için otomatik olarak anlar.

private val viewModel: MyViewModel by viewModels()
private val androidViewModel: MyAndroidViewModel by viewModels()

paylaşmak istersen ViewModel aynı aktivite içinde farklı parçalar arasında Kullanabilirsiniz by activityViewModels.

private val viewModel: MyViewModel by activityViewModels()
private val androidViewModel: MyAndroidViewModel 
    by activityViewModels()

viewModels tarafından (Özel Oluşturucu Parametresi)

Ek nesneleri göndermek çok yaygındır. ViewModel yapıcı. Aşağıdaki örnek geçiyor Repository içine nesne MyViewModel ve MyAndroidViewModel.

class MyViewModel(private val repository: Repository)
    : ViewModel() {
}

class MyAndroidViewModel(app: Application, repository: Repository)
    : AndroidViewModel(app) {
}

için özel bir kurucu parametresine sahip olmak ViewModel biraz karmaşıktır. bir adetin olması gerekiyor ViewModel fabrikanızı oluşturmak için ViewModel.

Özelinizi oluşturmak için ViewModel fabrika, miras alabilirsiniz ViewModelProvider.NewInstanceFactory.

class MyViewModelFactory(private val repository: Repository)
    : ViewModelProvider.NewInstanceFactory() {

    override fun <T : ViewModel> create(modelClass: Class<T>): T {

        if (modelClass.isAssignableFrom(MyViewModel::class.java)) {
            return MyViewModel(repository) as T
        }

        throw IllegalArgumentException("Unknown ViewModel class")
    }
}

özel için AndroidViewModel fabrika, miras alabilirsiniz ViewModelProvider.AndroidViewModelFactory

class MyAndroidViewModelFactory(
    private val app: Application,
    private val repository: Repository)
    : ViewModelProvider.AndroidViewModelFactory(app) {

    override fun <T : ViewModel> create(modelClass: Class<T>): T {

        if (modelClass.isAssignableFrom(
                MyAndroidViewModel::class.java)) {

            return MyAndroidViewModel(app, repository) as T
        }

        throw IllegalArgumentException("Unknown ViewModel class")
    }
}

Güncelleme: 30/10/2021: Aslında, sadece uygulayabiliriz ViewModelProvider.Factoryinterface her ikisi için MyViewModelFactory ve MyAndroidViewModelFactory. Örnekler bulunabilir burada.

Yaratmak ViewModel özel yapıcı parametrenizle by viewModels mülkü delege etmek.

private val viewModel: MyViewModel by viewModels {

    MyViewModelFactory(Repository())
}

private val androidViewModel: MyAndroidViewModel by viewModels {

    MyAndroidViewModelFactory(
        requireActivity().application,
        Repository())
}

değiştirebilirsiniz by viewModels ile birlikte by ActivityViewModels eğer istersen ViewModel aynı aktivite içinde farklı parçalarda hayatta kalmak için.

private val viewModel: MyAndroidViewModel by activityViewModels {

    MyViewModelFactory(Repository())
}

private val androidViewModel: MyAndroidViewModel 
    by activityViewModels {

        MyAndroidViewModelFactory(
            requireActivity().application,
            Repository())
    }

Güncelleme: 11/7/2021: Ayrıca kullanabilirsin by lazy ve ViewModelProvider() onun yerine by viewModels ve hala çalışması gerekir. Değiştirmek için kullanılamaz by activityViewModels çünkü yaratılmış ViewModelfarklı parçalar arasında paylaşılmayacaktır. Yani bu sadece referansınız ve bilginiz içindir.

private val viewModel: MyViewModel by lazy {
    val factory = MyViewModelFactory(Repository())

    ViewModelProvider(this, factory).get(MyAndroidViewModel::class.java)
}
private val viewModel: MyAndroidViewModel by lazy {
    val factory = MyAndroidViewModelFactory(
        requireActivity().application, 
        Repository())

    ViewModelProvider(this, factory).get(MyAndroidViewModel::class.java)
}

Ortak Uygulamalarım

Programlamanın eğlenceli yanı, aynı şeyi yapmanın birçok yolu olmasıdır. Farkları anlayın, sizi daha iyi bir programcı yapın.

ben kullanıyorum son yöntem varsayılan olarak, çünkü ViewModel’imde genellikle özel kurucu parametrelerim var.

Ayrıca, genellikle kullanırım by activityViewModels onun yerine by viewModels bu da verileri farklı parçalar arasında paylaşmamı sağlıyor. Verileri farklı parçalara nasıl aktaracağımı bulmak için zaman kazandırıyor. Örneğin, kullanarak Bundleparçalar arasında veri paylaşmak için.

ben de kullanıyorum AndroidViewModel yerine varsayılan olarak ViewModel çünkü genellikle dize kaynaklarına ve sistem hizmetlerine erişmem gerekiyor. Application bağlam. İnternette tartışılan dezavantajlar var ama bu kısmı henüz tam olarak anlamadım. Şimdilik, AndroidViewModel benim için iyi.

Bunlar benim genel uygulamalarım. Diğer Android geliştiricilerinin benimle aynı fikirde olduğundan emin değilim. Fikirlerinizi öğrenebilir miyim.

İlgili Makaleler

Bir cevap yazın

E-posta hesabınız yayımlanmayacak.

Başa dön tuşu