cap*_*uho 5 android android-fragments android-tablayout android-viewpager2
我需要根据服务器配置文件在运行时将片段添加到 viewpager2 以及选项卡。我见过的大多数 viewpager2 资源都展示了使用新 TabMediator 选项卡布局的静态 viewpager2。我正在跳过 viewpager,因为我需要添加 viewpager2 支持的 RTL 和垂直滚动。
我最关心的是当我添加和删除片段时如何跟踪特定页面/片段的索引。已完成本教程和代码作为示例。
这就是在 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()
Run Code Online (Sandbox Code Playgroud)
在这里,我们已经测试了在启动活动或父片段时使用一些基本延迟来添加和删除最后一个片段。您可以为每个选项卡创建自定义视图,或者为简单起见仅使用 tab.text =“选项卡名称”。
现在,您将与 ViewPager2 for 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()
}
}
Run Code Online (Sandbox Code Playgroud)
如果您的结构是“父片段”>“ViewPager2”>“子片段”,则上述代码将正常工作。
如果您的结构是“Activity”>“ViewPager2”>“Fragments”,只需更改
class AppFragmentAdapter(private val fragmentList: MutableList<Pair<String, Fragment>>, fragment: Fragment) : FragmentStateAdapter(fragment)
Run Code Online (Sandbox Code Playgroud)
到
class AppFragmentAdapter(private val fragmentList: MutableList<Pair<String, Fragment>>, fragment: FragmentActivity) : FragmentStateAdapter(fragment)
Run Code Online (Sandbox Code Playgroud)
然后代替
val adapter = AppFragmentAdapter(fragmentList, this)
Run Code Online (Sandbox Code Playgroud)
像这样传递 Fragment 的活动
val adapter = AppFragmentAdapter(fragmentList, requireActivity())
Run Code Online (Sandbox Code Playgroud)
我们的适配器内部FragmentStateAdapter(fragment)已经处理了应该使用哪个 FragmentManager。
活动 > ViewPager2 > 片段
public FragmentStateAdapter(@NonNull FragmentActivity fragmentActivity) {
this(fragmentActivity.getSupportFragmentManager(), fragmentActivity.getLifecycle());
}
Run Code Online (Sandbox Code Playgroud)
父片段 > ViewPager2 > 子片段
public FragmentStateAdapter(@NonNull Fragment fragment) {
this(fragment.getChildFragmentManager(), fragment.getLifecycle());
}
Run Code Online (Sandbox Code Playgroud)
在尝试我能想到的最简单的方法之前,我首先在 SO 中搜索有关使用 ViewPager2 动态添加/删除片段的信息,从而被欺骗了。
| 归档时间: |
|
| 查看次数: |
2669 次 |
| 最近记录: |