如何在 Kotlin 中使用带有选项卡的 ViewPager2?
How to use ViewPager2 with tabs in Kotlin?
实际上,在我的应用程序中,我有一个 activity,其中包含第一个片段,然后从该片段我可以按一些按钮导航到另一个片段,现在我将更改 activity 并添加一个 tablayout,我可以从中在我拥有的三个片段之间导航,但是通过阅读文档,我无法理解如何使用 ViewPager2 通过点击在其中显示我的片段在选项卡上。
我的 activity 布局现在看起来像这样:
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".LetturaActivity">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
app:elevation="0dp"
android:layout_height="wrap_content"
android:theme="@style/Theme.VisualStock.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/Theme.VisualStock.PopupOverlay" />
<com.google.android.material.tabs.TabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:elevation="8dp"
app:tabSelectedTextColor="#ffffff"
app:tabBackground="@drawable/tab_selector"
app:tabIndicatorGravity="top"
app:tabIndicatorColor="#ffffff"
app:tabMode="fixed">
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/riepilogo"
/>
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/testata"
/>
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/corpo"
/>
</com.google.android.material.tabs.TabLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/floatingActionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:clickable="true"
android:contentDescription="@string/menu_per_lo_scarico_nuovo_documento_o_riepilogo_articoli"
android:focusable="true"
app:fabSize="normal"
app:layout_anchor="@+id/pager"
app:layout_anchorGravity="end|bottom"
app:srcCompat="@drawable/ic_add"
app:tint="@android:color/white" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
然后我有三个像这样的片段文件:
class LetturaFragment : Fragment() {
...
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_lettura, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
...
}
}
class ArticoliFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_articoli, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
...
}
}
和activity
class LetturaActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_lettura)
}
如何使用我的片段在选项卡中导航并在 ViewPager2 中显示它们?
您需要使用适配器将 activity 与 ViewPager2 对象挂钩。见 here
您需要一个适配器才能将这些片段显示为 TabLayout
。
class PagerAdapter(fragmentActivity: FragmentActivity) :
FragmentStateAdapter(fragmentActivity) {
override fun createFragment(position: Int): Fragment {
when (position){
0 -> {
return LetturaFragment.newInstance(position)
}
1->{
return ArticoliFragment.newInstance(position)
}
}
return LetturaFragment.newInstance(position)
}
override fun getItemCount(): Int {
return ITEM_COUNT
}
companion object {
private const val ITEM_COUNT = 2
}
}
在您的 Fragment 中,定义伴生对象以获取这样的单个实例
class LetturaFragment : Fragment() {
...
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_lettura, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
...
}
companion object {
private const val ARG_COUNT = "param1"
fun newInstance(counter: Int?): LetturaFragment {
val fragment = LetturaFragment()
val args = Bundle()
args.putInt(ARG_COUNT, counter!!)
fragment.arguments = args
return fragment
}
}
}
其他子片段也一样
现在在你的 Activity
中,创建一个 TabLayoutMediator
到 link,TabLayout
到 ViewPager2
,并按如下方式附加它:
viewPager.adapter = PagerAdapter(this)
TabLayoutMediator(tabLayout, viewPager) { tab, position ->
tab.setText("$position + 1")
mainBinding.pager.setCurrentItem(tab.position, true)
}.attach()
有关详细信息,请阅读 this
你问的同样的事情我在我的项目中应用它也适用于你
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/root_layout_home_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.tabs.TabLayout
android:id="@+id/home_fragment_tabs"
android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize"
android:background="@drawable/gradianttoolbarbottom"
app:itemTextColor="@drawable/custom_menue_bar_color"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/constraintLayout3"
app:tabGravity="fill"
app:tabIndicatorColor="@color/Orange"
app:tabMode="scrollable"
app:tabSelectedTextColor="@color/white"
app:tabTextColor="@color/gray_400_dark" />
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/home_fragment_viewPager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:animateLayoutChanges="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/home_fragment_tabs" />
</androidx.constraintlayout.widget.ConstraintLayout>
这是 Kotlin class
class Home_Fragment : Fragment() {
private lateinit var homeViewModel: HomeFragmentViewModel
private var myContext: FragmentActivity? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
homeViewModel = ViewModelProvider(this).get(HomeFragmentViewModel::class.java)
val root = inflater.inflate(R.layout.fragment_home, container, false)
myContext=activity
val viewpagger: ViewPager2 =root.findViewById<ViewPager2>(R.id.home_fragment_viewPager)
viewpagger.isSaveEnabled=false
val tabs: TabLayout = root.findViewById<TabLayout>(R.id.home_fragment_tabs)
val adapter =MyViewPagerAdapter(childFragmentManager,lifecycle)
adapter.addFragment(Fragment1(), getString(R.string.text_Fragment1))
adapter.addFragment(Fragment2(), getString(R.string.text_Fragment2))
adapter.addFragment(Fragment3(), getString(R.string.text_Fragment3))
adapter.addFragment(Fragment4(),getString(R.string.text_Fragment4))
adapter.addFragment(Fragment5(), getString(R.string.text_Fragment5))
adapter.notifyDataSetChanged()
viewpagger.adapter =adapter
TabLayoutMediator(tabs, viewpagger) { tab, position ->
tab.text = adapter.getPageTitle(position)
viewpagger.setCurrentItem(tab.position, true)
}.attach()
return root
}
class MyViewPagerAdapter(manager: FragmentManager, lifecycle: Lifecycle) : FragmentStateAdapter(manager,lifecycle ){
private val fragmentList : MutableList<Fragment> =ArrayList()
private val titleList : MutableList<String> =ArrayList()
override fun getItemCount(): Int {
return fragmentList.size
}
override fun createFragment(position: Int): Fragment {
return fragmentList[position]
}
fun addFragment(fragment: Fragment, title: String){
fragmentList.add(fragment)
titleList.add(title)
}
fun getPageTitle(position: Int): CharSequence? {
return titleList[position]
}
}
}
按如下方式使用此 TabLayoutMediator after you set adapter to ViewPager2
TabLayoutMediator(tab_layout, view_pager) { tab, position ->
tab.text = fragmentList[position].second
}.attach()
实际上,在我的应用程序中,我有一个 activity,其中包含第一个片段,然后从该片段我可以按一些按钮导航到另一个片段,现在我将更改 activity 并添加一个 tablayout,我可以从中在我拥有的三个片段之间导航,但是通过阅读文档,我无法理解如何使用 ViewPager2 通过点击在其中显示我的片段在选项卡上。
我的 activity 布局现在看起来像这样:
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".LetturaActivity">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
app:elevation="0dp"
android:layout_height="wrap_content"
android:theme="@style/Theme.VisualStock.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/Theme.VisualStock.PopupOverlay" />
<com.google.android.material.tabs.TabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:elevation="8dp"
app:tabSelectedTextColor="#ffffff"
app:tabBackground="@drawable/tab_selector"
app:tabIndicatorGravity="top"
app:tabIndicatorColor="#ffffff"
app:tabMode="fixed">
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/riepilogo"
/>
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/testata"
/>
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/corpo"
/>
</com.google.android.material.tabs.TabLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/floatingActionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:clickable="true"
android:contentDescription="@string/menu_per_lo_scarico_nuovo_documento_o_riepilogo_articoli"
android:focusable="true"
app:fabSize="normal"
app:layout_anchor="@+id/pager"
app:layout_anchorGravity="end|bottom"
app:srcCompat="@drawable/ic_add"
app:tint="@android:color/white" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
然后我有三个像这样的片段文件:
class LetturaFragment : Fragment() {
...
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_lettura, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
...
}
}
class ArticoliFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_articoli, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
...
}
}
和activity
class LetturaActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_lettura)
}
如何使用我的片段在选项卡中导航并在 ViewPager2 中显示它们?
您需要使用适配器将 activity 与 ViewPager2 对象挂钩。见 here
您需要一个适配器才能将这些片段显示为 TabLayout
。
class PagerAdapter(fragmentActivity: FragmentActivity) :
FragmentStateAdapter(fragmentActivity) {
override fun createFragment(position: Int): Fragment {
when (position){
0 -> {
return LetturaFragment.newInstance(position)
}
1->{
return ArticoliFragment.newInstance(position)
}
}
return LetturaFragment.newInstance(position)
}
override fun getItemCount(): Int {
return ITEM_COUNT
}
companion object {
private const val ITEM_COUNT = 2
}
}
在您的 Fragment 中,定义伴生对象以获取这样的单个实例
class LetturaFragment : Fragment() {
...
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_lettura, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
...
}
companion object {
private const val ARG_COUNT = "param1"
fun newInstance(counter: Int?): LetturaFragment {
val fragment = LetturaFragment()
val args = Bundle()
args.putInt(ARG_COUNT, counter!!)
fragment.arguments = args
return fragment
}
}
}
其他子片段也一样
现在在你的 Activity
中,创建一个 TabLayoutMediator
到 link,TabLayout
到 ViewPager2
,并按如下方式附加它:
viewPager.adapter = PagerAdapter(this)
TabLayoutMediator(tabLayout, viewPager) { tab, position ->
tab.setText("$position + 1")
mainBinding.pager.setCurrentItem(tab.position, true)
}.attach()
有关详细信息,请阅读 this
你问的同样的事情我在我的项目中应用它也适用于你
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/root_layout_home_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.tabs.TabLayout
android:id="@+id/home_fragment_tabs"
android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize"
android:background="@drawable/gradianttoolbarbottom"
app:itemTextColor="@drawable/custom_menue_bar_color"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/constraintLayout3"
app:tabGravity="fill"
app:tabIndicatorColor="@color/Orange"
app:tabMode="scrollable"
app:tabSelectedTextColor="@color/white"
app:tabTextColor="@color/gray_400_dark" />
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/home_fragment_viewPager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:animateLayoutChanges="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/home_fragment_tabs" />
</androidx.constraintlayout.widget.ConstraintLayout>
这是 Kotlin class
class Home_Fragment : Fragment() {
private lateinit var homeViewModel: HomeFragmentViewModel
private var myContext: FragmentActivity? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
homeViewModel = ViewModelProvider(this).get(HomeFragmentViewModel::class.java)
val root = inflater.inflate(R.layout.fragment_home, container, false)
myContext=activity
val viewpagger: ViewPager2 =root.findViewById<ViewPager2>(R.id.home_fragment_viewPager)
viewpagger.isSaveEnabled=false
val tabs: TabLayout = root.findViewById<TabLayout>(R.id.home_fragment_tabs)
val adapter =MyViewPagerAdapter(childFragmentManager,lifecycle)
adapter.addFragment(Fragment1(), getString(R.string.text_Fragment1))
adapter.addFragment(Fragment2(), getString(R.string.text_Fragment2))
adapter.addFragment(Fragment3(), getString(R.string.text_Fragment3))
adapter.addFragment(Fragment4(),getString(R.string.text_Fragment4))
adapter.addFragment(Fragment5(), getString(R.string.text_Fragment5))
adapter.notifyDataSetChanged()
viewpagger.adapter =adapter
TabLayoutMediator(tabs, viewpagger) { tab, position ->
tab.text = adapter.getPageTitle(position)
viewpagger.setCurrentItem(tab.position, true)
}.attach()
return root
}
class MyViewPagerAdapter(manager: FragmentManager, lifecycle: Lifecycle) : FragmentStateAdapter(manager,lifecycle ){
private val fragmentList : MutableList<Fragment> =ArrayList()
private val titleList : MutableList<String> =ArrayList()
override fun getItemCount(): Int {
return fragmentList.size
}
override fun createFragment(position: Int): Fragment {
return fragmentList[position]
}
fun addFragment(fragment: Fragment, title: String){
fragmentList.add(fragment)
titleList.add(title)
}
fun getPageTitle(position: Int): CharSequence? {
return titleList[position]
}
}
}
按如下方式使用此 TabLayoutMediator after you set adapter to ViewPager2
TabLayoutMediator(tab_layout, view_pager) { tab, position ->
tab.text = fragmentList[position].second
}.attach()