我在我的应用程序中使用ViewPager2。我有以下代码将适配器设置为ViewPager:
viewModel.creditWrapper.observe(viewLifecycleOwner, Observer { creditWrapper ->
fragmentManager?.let {
val myAdapter = ViewPagerFragmentAdapter(it, lifecycle)
val castPagerItem = PagerItem(CreditFragment.newInstance(tmdbItem,
creditWrapper.cast as ArrayList<Cast>), R.string.cast)
val crewPagerItem = PagerItem(CreditFragment.newInstance(tmdbItem,
creditWrapper.crew as ArrayList<Crew>), R.string.crew)
myAdapter.addFragment(castPagerItem)
myAdapter.addFragment(crewPagerItem)
pager.adapter = myAdapter
TabLayoutMediator(tab_layout, pager) { tab, position ->
tab.text = getString(myAdapter.creditFragments[position].title)
}.attach()
}
})
如您所见,我多次将tmdbItem作为参数传递给newInstance()方法。有什么解决方案可以避免这种情况,并且不要多次传递参数?这是我的CreditFragment:
class CreditFragment<T : Credit> : Fragment() {
companion object {
private const val TMDB_ITEM = "tmdb_item"
private const val CREDITS = "credits"
@JvmStatic
fun <T : Credit> newInstance(item: TmdbItem, credits: ArrayList<T>) =
CreditFragment<T>().apply {
arguments = Bundle(2).apply {
putParcelable(TMDB_ITEM, item)
putParcelableArrayList(CREDITS, credits)
}
}
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
val root = inflater.inflate(R.layout.credit_fragment, container, false)
root.credit_list.apply {
setHasFixedSize(true)
adapter = arguments?.getParcelableArrayList<T>(CREDITS)?.let {
CreditAdapter(it, object : CreditClickCallback {
override fun onClick(personId: Any, personName: String, profilePath: String?) {
val intent = Intent(activity, PersonActivity::class.java).apply {
putExtras(Bundle().apply {
putParcelable(PERSON_WRAPPER, PersonWrapper(personId,
personName,
profilePath,
arguments?.getParcelable<TmdbItem>(TMDB_ITEM)?.backdropPath))
})
}
startActivity(intent)
}
})
}
}
return root
}
}
完整的源代码可以在以下位置找到:https://github.com/Ali-Rezaei/TMDb-Paging 最佳答案
我认为您的代码还可以。我看到您有很多代码移至抽象/父类。如果您觉得还可以,那么我认为您无能为力。通过这种方法,您将创建大量的耦合,并且失去了灵活性,但是正如我所说的那样-如果它对您有用,并且您知道您将不需要它,那么就可以。
您正在使用工厂方法传递参数,这是一个很好的方法,对我来说,这是完全可以接受的。如果您试图变得越来越通用,并且您的目标是尽可能减少重复的代码,那么正如我所说的那样,您可能会失去灵活性。
因此,可以从Fragment / Activity或应用程序的下层获取tmdbItem。当然,您可以使用DI框架注入(inject)某种TmdbItemProvider,但我认为这不是一个好主意,因为您可能会遇到瓶颈,并且无法控制tmdbItem的状态。
对我来说,这还可以,一点点重复就不会杀死任何人;)
我还将考虑研究Composition over Inheritance的主题