Saya mencoba menambahkan Belati 2 ke proyek saya. Saya dapat menyuntikkan ViewModels (komponen Arsitektur AndroidX) untuk fragmen saya.
Saya memiliki ViewPager yang memiliki 2 contoh fragmen yang sama (Hanya sedikit perubahan untuk setiap tab) dan di setiap tab, saya mengamati LiveDatauntuk mendapatkan pembaruan tentang perubahan data (dari API).
Masalahnya adalah ketika respons api datang dan memperbarui LiveData, data yang sama dalam fragmen yang saat ini terlihat dikirim ke pengamat di semua tab. (Saya pikir ini mungkin karena ruang lingkupnya ViewModel).
Inilah cara saya mengamati data saya:
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
activityViewModel.expenseList.observe(this, Observer {
swipeToRefreshLayout.isRefreshing = false
viewAdapter.setData(it)
})
....
}
Saya menggunakan kelas ini untuk menyediakan ViewModels:
class ViewModelProviderFactory @Inject constructor(creators: MutableMap<Class<out ViewModel?>?, Provider<ViewModel?>?>?) :
ViewModelProvider.Factory {
private val creators: MutableMap<Class<out ViewModel?>?, Provider<ViewModel?>?>? = creators
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
var creator: Provider<out ViewModel?>? = creators!![modelClass]
if (creator == null) { // if the viewmodel has not been created
// loop through the allowable keys (aka allowed classes with the @ViewModelKey)
for (entry in creators.entries) { // if it's allowed, set the Provider<ViewModel>
if (modelClass.isAssignableFrom(entry.key!!)) {
creator = entry.value
break
}
}
}
// if this is not one of the allowed keys, throw exception
requireNotNull(creator) { "unknown model class $modelClass" }
// return the Provider
return try {
creator.get() as T
} catch (e: Exception) {
throw RuntimeException(e)
}
}
companion object {
private val TAG: String? = "ViewModelProviderFactor"
}
}
Saya mengikat saya ViewModelseperti ini:
@Module
abstract class ActivityViewModelModule {
@MainScope
@Binds
@IntoMap
@ViewModelKey(ActivityViewModel::class)
abstract fun bindActivityViewModel(viewModel: ActivityViewModel): ViewModel
}
Saya menggunakan @ContributesAndroidInjectoruntuk fragmen saya seperti ini:
@Module
abstract class MainFragmentBuildersModule {
@ContributesAndroidInjector
abstract fun contributeActivityFragment(): ActivityFragment
}
Dan saya menambahkan modul ini ke MainActivitysubkomponen saya seperti ini:
@Module
abstract class ActivityBuilderModule {
...
@ContributesAndroidInjector(
modules = [MainViewModelModule::class, ActivityViewModelModule::class,
AuthModule::class, MainFragmentBuildersModule::class]
)
abstract fun contributeMainActivity(): MainActivity
}
Ini milik saya AppComponent:
@Singleton
@Component(
modules =
[AndroidSupportInjectionModule::class,
ActivityBuilderModule::class,
ViewModelFactoryModule::class,
AppModule::class]
)
interface AppComponent : AndroidInjector<SpenmoApplication> {
@Component.Builder
interface Builder {
@BindsInstance
fun application(application: Application): Builder
fun build(): AppComponent
}
}
Saya memperpanjang DaggerFragmentdan menyuntikkan ViewModelProviderFactoryseperti ini:
@Inject
lateinit var viewModelFactory: ViewModelProviderFactory
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
....
activityViewModel =
ViewModelProviders.of(this, viewModelFactory).get(key, ActivityViewModel::class.java)
activityViewModel.restartFetch(hasReceipt)
}
yang keyakan berbeda untuk kedua fragmen.
Bagaimana saya bisa memastikan bahwa hanya pengamat fragmen saat ini yang diperbarui.
EDIT 1 ->
Saya telah menambahkan proyek sampel dengan kesalahan. Sepertinya masalah hanya terjadi ketika ruang lingkup kustom ditambahkan. Silakan periksa contoh proyek di sini: Tautan Github
mastercabang memiliki aplikasi dengan masalah ini. Jika Anda me-refresh tab apa pun (gesek untuk menyegarkan) nilai yang diperbarui tercermin di kedua tab. Ini hanya terjadi ketika saya menambahkan ruang lingkup kustom untuk itu ( @MainScope).
working_fine cabang memiliki aplikasi yang sama tanpa ruang lingkup khusus dan berfungsi dengan baik.
Tolong beri tahu saya jika pertanyaannya tidak jelas.
working_finecabang? Mengapa Anda membutuhkan ruang lingkup?