【问题标题】:How do I dynamically add and remove fragment pages using Viewpager2 and Mediator Tab Layout如何使用 Viewpager2 和 Mediator 选项卡布局动态添加和删除片段页面
【发布时间】:2020-02-08 19:01:25
【问题描述】:

我需要根据服务器配置文件在运行时将片段添加到 viewpager2 以及选项卡。 我见过的大多数 viewpager2 资源都展示了使用新 TabMediator 选项卡布局的静态 viewpager2。 我正在跳过 viewpager,因为我需要添加 viewpager2 支持的 RTL 和垂直滚动。

我最关心的是如何在添加和删除片段时跟踪特定页面/片段的索引。 以this教程和代码为例。

【问题讨论】:

  • 你找到答案了吗?
  • 这帮助我解决了我的问题 - stackoverflow.com/questions/61406176/…
  • 会检查的。
  • @artman 这不是正确的解决方案。如果我只有一个片段并尝试浏览具有不同数据的不同选项卡。
  • @cap_muho 如果您找到任何解决方案,请告诉我。

标签: android android-fragments android-tablayout android-viewpager2


【解决方案1】:

这就是你在 Kotlin 中实现它的方式

viewPager = binding.viewPagerContainer
        val tabLayout : TabLayout = binding.tabLayout

        val fragmentList : MutableList<Pair<String, Fragment>> = mutableListOf()
        fragmentList.add(Pair(getString(R.string.assets), AssetFragment.newInstance()))
        fragmentList.add(Pair(getString(R.string.news), NewsFragment.newInstance()))

        val adapter = AppFragmentAdapter(fragmentList, this)

        Handler(Looper.myLooper()!!).postDelayed({
            adapter.addFragment(Pair(getString(R.string.videos), VideosFragment.newInstance()))
        }, 1000)

        Handler(Looper.myLooper()!!).postDelayed({
            adapter.removeFragment(2)
        }, 2000)

        viewPager.adapter = adapter
        viewPager.offscreenPageLimit = 2

        val layoutInflater : LayoutInflater = LayoutInflater.from(context)

        viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {

            override fun onPageSelected(position: Int) {
                super.onPageSelected(position)
                val actionBar : ActionBar = (requireActivity() as AppCompatActivity).supportActionBar!!
                actionBar.title = adapter.getFragmentName(position)
            }

        })

        TabLayoutMediator(tabLayout, viewPager){ tab, position ->
            tab.customView = prepareTabView(layoutInflater, tabLayout, adapter.getFragmentName(position), tabIcons[position])
        }.attach()

在这里,我们已经测试了在启动 Activity 或父 Fragment 时使用一些基本延迟来添加和删除最后一个 Fragment。您可以为每个选项卡创建自定义视图,或者为简单起见仅使用 tab.text = "Tab Name"。

现在,您将与 ViewPager2 一起使用的 Fragment 适配器类型是 FragmentStateAdapter

class AppFragmentAdapter(private val fragmentList: MutableList<Pair<String, Fragment>>, fragment: Fragment) : FragmentStateAdapter(fragment) {

//    private var pageIds = fragmentList.map { fragmentList.hashCode().toLong() }

    override fun getItemCount(): Int = fragmentList.size

    override fun createFragment(position: Int): Fragment {
        return fragmentList[position].second
    }

//    override fun getItemId(position: Int): Long = pageIds[position] // Make sure notifyDataSetChanged() works

//    override fun containsItem(itemId: Long): Boolean = pageIds.contains(itemId)

    fun getFragmentName(position: Int) = fragmentList[position].first

    fun addFragment(fragment: Pair<String, Fragment>) {
        fragmentList.add(fragment)
        notifyDataSetChanged()
    }

    fun removeFragment(position: Int) {
        fragmentList.removeAt(position)
        notifyDataSetChanged()
    }

}

如果你的结构是 Parent Fragment > ViewPager2 > Child Fragments 上面的代码可以正常工作。

如果你的结构是 Activity > ViewPager2 > Fragments just change

class AppFragmentAdapter(private val fragmentList: MutableList<Pair<String, Fragment>>, fragment: Fragment) : FragmentStateAdapter(fragment)

class AppFragmentAdapter(private val fragmentList: MutableList<Pair<String, Fragment>>, fragment: FragmentActivity) : FragmentStateAdapter(fragment)

然后代替

val adapter = AppFragmentAdapter(fragmentList, this)

像这样传递 Fragment 的活动

val adapter = AppFragmentAdapter(fragmentList, requireActivity())

来自我们适配器的内部FragmentStateAdapter(fragment) 已经处理了应该使用的 FragmentManager。

活动 > ViewPager2 > 片段

public FragmentStateAdapter(@NonNull FragmentActivity fragmentActivity) {
    this(fragmentActivity.getSupportFragmentManager(), fragmentActivity.getLifecycle());
}

父片段 > ViewPager2 > 子片段

public FragmentStateAdapter(@NonNull Fragment fragment) {
    this(fragment.getChildFragmentManager(), fragment.getLifecycle());
}

我是deceived,首先在 SO 中搜索关于使用 ViewPager2 动态添加/删除片段,然后再尝试我能想到的最简单的方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-27
    • 2020-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-27
    • 1970-01-01
    相关资源
    最近更新 更多