如何在 Android 中使用 TabLayout 和 ViewPager2

新手上路,请多包涵

我想使用 com.google.android.material.tabs.TabLayout 组件与 Android 的新 ViewPager 实现 androidx.viewpager2.widget.ViewPager2 。但是, setupWithViewPager(..) TabLayout 只支持旧的 ViewPager 实现。有没有办法轻松地将 TabLayout 绑定到 ViewPager2 组件?

原文由 Ugurcan Yildirim 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 892
2 个回答

You have to use this TabLayoutMediator that tabLayout.setupWithViewPager() and sets up the ViewPager2 with Tablayout .否则,您将不得不编写自己的适配器来结合双方。

它的代码在 Kotlin 中看起来像这样

TabLayoutMediator(tabLayout, viewPager) { tab, position ->
  tab.text = tabTitles[position]
}.attach()

原文由 Nikola Despotoski 发布,翻译遵循 CC BY-SA 4.0 许可协议

没有黑客,没有扩展,没有 TabLayoutMediator

我在 implementation 'com.google.android.material:material:1.2.0-alpha02' 并在 不需要 TabLayoutMediator 的情况下执行以下操作。相反,我使用 此处 描述的方法将 TabLayout 与 ViewPager2 链接起来。我还在 github here 中添加了一个工作示例。我想我已经将解决方案最小化为一个最小的工作示例。我将解释重要的部分。

将元素添加到模板

首先,我们需要将 TabLayout 和 ViewPager2 添加到布局中。我在这里将它们放在 LinearLayout 和 CoordinatorLayout 中,但是你当然可以做任何你喜欢的事情。

 <!-- activity_main.xml -->
<?xml version="1.0" encoding="utf-8"?>
<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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <com.google.android.material.tabs.TabLayout
                android:id="@+id/tabLayout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>
            <androidx.viewpager2.widget.ViewPager2
                android:id="@+id/pager"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>

        </LinearLayout>

    </androidx.coordinatorlayout.widget.CoordinatorLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

将适配器连接到 viewpager

因此适配器负责为活动提供正确的片段。您必须扩展 FragmentStateAdapter ,我已经非常简单地完成了它,如下所示(它是一个私有类,因为它是在我的 MainActivity.java 中声明的):

     private class ViewStateAdapter extends FragmentStateAdapter {

        public ViewStateAdapter(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle) {
            super(fragmentManager, lifecycle);
        }

        @NonNull
        @Override
        public Fragment createFragment(int position) {
            // Hardcoded in this order, you'll want to use lists and make sure the titles match
            if (position == 0) {
                return new BarFragment();
            }
            return new FooFragment();
        }

        @Override
        public int getItemCount() {
            // Hardcoded, use lists
            return 2;
        }
    }

然后我可以将我自己的适配器连接到 ViewPager,如下所示:

 FragmentManager fm = getSupportFragmentManager();
ViewStateAdapter sa = new ViewStateAdapter(fm, getLifecycle());
final ViewPager2 pa = findViewById(R.id.pager);
pa.setAdapter(sa);

我已将这些片段添加到我的 viewpager 中。 (因为我在我的适配器中硬编码了片段,你应该使用一个列表和类似“addFragment”方法之类的东西)

选项卡布局

然后用

TabLayout tabLayout = findViewById(R.id.tabLayout);
tabLayout.addTab(tabLayout.newTab().setText("Bar"));
tabLayout.addTab(tabLayout.newTab().setText("Foo"));

我向我的 TabLayout 添加了两个选项卡,显示标题但还不允许我切换到片段。

将 TabLayout 连接到适配器

tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                pa.setCurrentItem(tab.getPosition());
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {

            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {

            }
        });

这应该非常简单。用户单击一个选项卡,我在回调中获得位置,我只需将适配器的当前项设置到该位置。

滑动时更改选项卡

最后,当用户滑动片段以将正确的选项卡项设置为选中时,我们会返回

pa.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
    @Override
    public void onPageSelected(int position) {
        tabLayout.selectTab(tabLayout.getTabAt(position));
    }
});

原文由 Potential Guacamole 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题