我在我的应用程序中使用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的主题

08-05 19:24