1 | initial version |
To use Koin to achieve the use of the same fragment type in a viewpager but with different instances of viewmodel in each tab, with varying parameters, you can follow these steps:
class MyViewModelFactory(private val param1: String, private val param2: Int) : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return modelClass.getConstructor(String::class.java, Int::class.java)
.newInstance(param1, param2)
}
}
val myModule = module {
factory { (param1: String, param2: Int) -> MyViewModelFactory(param1, param2) }
factory { (param1: String, param2: Int) -> MyViewModel(param1, param2) }
}
class MyFragment : Fragment() {
private val viewModelFactory by inject<(String, Int) -> ViewModelProvider.Factory>()
private lateinit var viewModel: MyViewModel
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val position = arguments?.getInt("position") ?: 0
val param1 = "param1 for tab $position"
val param2 = position
viewModel = ViewModelProvider(this, viewModelFactory(param1, param2)).get(MyViewModel::class.java)
}
}
class MyViewPagerAdapter(fragmentManager: FragmentManager) : FragmentStatePagerAdapter(fragmentManager) {
override fun getItem(position: Int): Fragment {
val args = Bundle()
args.putInt("position", position)
val fragment = MyFragment()
fragment.arguments = args
return fragment
}
override fun getCount(): Int {
return 3
}
}
With this approach, you can reuse the same MyFragment instance in each tab of the ViewPager but with different instances of MyViewModel, each with varying parameters.