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 LiveData
untuk 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 ViewModel
s:
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 ViewModel
seperti ini:
@Module
abstract class ActivityViewModelModule {
@MainScope
@Binds
@IntoMap
@ViewModelKey(ActivityViewModel::class)
abstract fun bindActivityViewModel(viewModel: ActivityViewModel): ViewModel
}
Saya menggunakan @ContributesAndroidInjector
untuk fragmen saya seperti ini:
@Module
abstract class MainFragmentBuildersModule {
@ContributesAndroidInjector
abstract fun contributeActivityFragment(): ActivityFragment
}
Dan saya menambahkan modul ini ke MainActivity
subkomponen 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 DaggerFragment
dan menyuntikkan ViewModelProviderFactory
seperti 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 key
akan 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
master
cabang 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_fine
cabang? Mengapa Anda membutuhkan ruang lingkup?