没有 hack、没有扩展、没有 TabLayoutMediator
我在implementation 'com.google.android.material:material:1.2.0-alpha02' 上并执行以下操作而不需要 TabLayoutMediator。
相反,我使用here 描述的方法将 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);
我已将片段添加到我的浏览器中。 (因为我在适配器中对 Fragments 进行了硬编码,所以您应该使用列表和类似“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));
}
});