ViewPager2 adapters - difference between FragmentActivity / Fragment / FragmentManager

让人想犯罪 __ 提交于 2021-01-29 21:15:53

问题


I noticed in this ViewPager2 video that there are 3 different ways of declaring an adapter with Fragments. What's the difference between them and which 1 should be used for swipe views with tabs using ViewPager2?

Option 1 (recommended)

class MyFragmentAdapter (
    fa: FragmentActivity
) : FragmentStateAdapter(fa)

Option 2

class MyFragmentAdapter (
    f: Fragment
) : FragmentStateAdapter(f)

Option 3

class MyFragmentAdapter (
    fm: FragmentManager,
    l: Lifecycle
) : FragmentStateAdapter(fm, l)

回答1:


These classes are all inheriting from FragmentStateAdapter. There are even more ways. You mentioned, you want to swipe between fragments in a ViewPager. Then it might be an advantage to hold neighboring fragments in memory, without destroying them. In case you don't have too many pages, I would recommend to use FragmentPagerAdapter instead. When you got a lot of fragments, you should rather use FragmentStatePagerAdapter, which is similar to FragmentStateAdapter, to improve performance.

Here is a working example:

MyPagerAdapter.kt

class MyPagerAdapter(fragmentManager: FragmentManager, private val fragments: List<Fragment>)
    : FragmentPagerAdapter(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {

    private val retainedFragments: SparseArray<Fragment> = SparseArray()

    override fun getItem(position: Int): Fragment {
        return if (retainedFragments.get(position) != null)
            retainedFragments.get(position)
        else
            fragments[position]
    }

    override fun getCount() = this.fragments.size

    override fun instantiateItem(container: ViewGroup, position: Int): Any {
        val fragment = super.instantiateItem(container, position) as Fragment
        retainedFragments.put(position, fragment)

        return fragment
    }

    override fun destroyItem(container: ViewGroup, position: Int, view: Any) {
        if (retainedFragments.get(position) != null) {
            retainedFragments.remove(position)
        }
        super.destroyItem(container, position, view)
    }

    override fun getPageTitle(position: Int): CharSequence? {
        return if (position == 0)
            context?.getString(R.string.bars_title)
        else
            context?.getString(R.string.bars_title_presets)
    }
}

Then in your host Fragment/Activity, in this case the host is a Fragment with DataBinding (not relevant here):

class HostFragment : Fragment() {
    private lateinit var pagerAdapter: MyPagerAdapter
    private val fragments: MutableList<Fragment> = mutableListOf()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        fragments.add(MyTabFragment.newInstance(0))
        fragments.add(MyTabFragment.newInstance(1))
        pagerAdapter = MyPagerAdapter(childFragmentManager, fragments)
        pagerAdapter.notifyDataSetChanged()
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        setHasOptionsMenu(false)
        val binding: FragmentBarsBinding =
            DataBindingUtil.inflate(inflater,R.layout.fragment_host, container, false)
        binding.apply {
            pager.adapter = pagerAdapter
            tabs.setupWithViewPager(pager,true)
        }
        return binding.root
    }
}



回答2:


With Viewpager2 there is only one adapter type FragmentStateAdapter

There does not seem to be a difference in how they behave, they are just different constructors of the same FragmentStateAdapter. Which one to use seems to mostly depend on where you are creating the viewpager2

Give it a FragmentActivity if you are creating the viewpager2 in an Activity, this is a shortcut to the third method

Give is a Fragment if you are creating the viewpager2 in a parent Fragement, this is a shortcut to the third method

The third of FragmentManager and Lifecycle is actually what it requires to work, see the source code for viewpager2 constructors https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-master-dev/viewpager2/viewpager2/src/main/java/androidx/viewpager2/adapter/FragmentStateAdapter.java#109



来源:https://stackoverflow.com/questions/60960621/viewpager2-adapters-difference-between-fragmentactivity-fragment-fragmentm

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!