这是从 ViewPager 的片段中作为问题状态的详细片段的答案。
我还通过将 viewPager 放入片段中使其变得有点复杂,如果您愿意,可以跳过并将其添加到活动中。
- 为 Activity 创建布局
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="@style/ThemeOverlay.AppCompat.ActionBar" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/fragment_container_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
FragmentContainerView 包含具有ViewPager2 的片段
// Replace Fragment with DSL style
supportFragmentManager.commit {
replace<FragmentThatContainsViewPager>(R.id.fragment_container_view)
}
FragmentThatContainsViewPager 的布局
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:tabMode="scrollable" />
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tabLayout" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
容器片段代码
class FragmentThatContainsViewPager : BaseDataBindingFragment<FragmentWithViewpagerBinding>() {
override fun getLayoutRes(): Int {
return R.layout.fragment_with_viewpager
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return super.onCreateView(inflater, container, savedInstanceState)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// TabLayout
val tabLayout = dataBinding.tabLayout
// ViewPager2
val viewPager = dataBinding.viewPager
/*
? Set Adapter for ViewPager inside this fragment using this Fragment,
more specifically childFragmentManager as param
*/
viewPager.adapter = ChildFragmentStateAdapter(this)
// Bind tabs and viewpager
TabLayoutMediator(tabLayout, viewPager) { tab, position ->
tab.text = "Tab $position"
}.attach()
}
}
ViewPager 的适配器,如果你希望我使用FragmentFactory,你可以使用 GenericFragmentParent.newInstance()
class ChildFragmentStateAdapter(private val fragment: Fragment) :
FragmentStateAdapter(片段) {
private val genericFragmentFactory = GenericFragmentFactory.getFragmentFactory()
override fun getItemCount(): Int = 5
override fun createFragment(position: Int): Fragment {
genericFragmentFactory.fragID = position
return genericFragmentFactory.instantiate(
fragment.requireActivity().classLoader,
GenericFragmentParent::class.java.name
)
}
}
class GenericFragmentParent(private val fragID: Int) :
BaseDataBindingFragment<FragmentGenericParentBinding>() {
override fun getLayoutRes(): Int {
return R.layout.fragment_generic_parent
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
dataBinding.btnNextPage.setOnClickListener {
/*
?? Replacing in container in Activity for both fragments to
be in same stack of supportFragmentManager
*/
requireActivity().supportFragmentManager.commit {
replace<GenericChildFragment>(R.id.fragment_container_view)
.addToBackStack(null)
}
}
}
}
还使用返回堆栈计数在顶部显示返回箭头
supportFragmentManager.addOnBackStackChangedListener {
val fragmentOnTop = supportFragmentManager.findFragmentById(
R.id.fragment_container_view
)
val fragmentCount = supportFragmentManager.backStackEntryCount
supportActionBar?.setDisplayHomeAsUpEnabled(fragmentCount > 0)
}
还有
override fun onSupportNavigateUp(): Boolean {
supportFragmentManager.popBackStack()
return true
}
触摸返回箭头时删除片段。
我添加了示例here,它在 MaterialDesign 模块中,可能为 ViewPager 选项卡的子片段的导航添加了另一个示例,每个子片段都有自己的子片段,而不是打开细节片段
而您可以滑动 ViewPager2 的相邻片段