Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/211.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在Android中与ViewPager2一起使用TabLayout_Java_Android_Androidx_Android Tablayout_Android Viewpager2 - Fatal编程技术网

Java 如何在Android中与ViewPager2一起使用TabLayout

Java 如何在Android中与ViewPager2一起使用TabLayout,java,android,androidx,android-tablayout,android-viewpager2,Java,Android,Androidx,Android Tablayout,Android Viewpager2,我想将com.google.android.material.tabs.TabLayout组件与android的新ViewPager实现androidx.viewpager2.widget.viewpager2一起使用。但是,TabLayout提供的setupWithViewPager(..)方法仅支持旧的ViewPager实现。有没有一种方法可以轻松地将TabLayout绑定到ViewPager2组件?您必须使用模仿TabLayout.setupWithViewPager()的TabLayou

我想将
com.google.android.material.tabs.TabLayout
组件与android的新
ViewPager
实现
androidx.viewpager2.widget.viewpager2
一起使用。但是,
TabLayout
提供的
setupWithViewPager(..)
方法仅支持旧的
ViewPager
实现。有没有一种方法可以轻松地将
TabLayout
绑定到
ViewPager2
组件?

您必须使用模仿
TabLayout.setupWithViewPager()
TabLayoutMediator
来设置
ViewPager2
。否则,您将不得不编写自己的适配器来合并双方

它的代码在kotlin中是这样的

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

使用
TabLayout
对象、
ViewPager2
autoRefresh
--布尔类型和
OnConfigurationChangeCallback
对象初始化
TabLayoutMediator
对象

TabLayoutMediator tabLayoutMediator = new TabLayoutMediator(tabLayout, viewPager2, true, new TabLayoutMediator.OnConfigureTabCallback() {
  @Override
  public void onConfigureTab(TabLayout.Tab tab, int position) {
    // position of the current tab and that tab  
  }
});
最后,只需调用
attach()
TabLayoutMediator
对象,将tablayout连接到viewpager:-

autoRefresh
-如果设置为
true
,则按键(默认设置为true)

如果对viewpager
适配器调用了
notifyDataSetChanged
,则重新创建
表格布局的所有选项卡

使用更新的内容 检查这个 以下是更新后的答案如何在Android中与ViewPager2一起使用TabLayout

现在我们不需要从
tablayoutcommediator
使用下面的依赖项

implementation 'com.google.android.material:material:1.1.0-alpha08'
implementation 'androidx.viewpager2:viewpager2:1.0.0-beta02'
示例代码

XMl布局

更新

如果您使用的是
实现'com.google.android.material:material:1.1.0-alpha10'
,请使用下面的代码

        TabLayoutMediator(tabs, viewpage,
        TabLayoutMediator.TabConfigurationStrategy { tab, position ->
            when (position) {
                0 -> { tab.text = "TAB ONE"}
                1 -> { tab.text = "TAB TWO"}
            }
        }).attach()
输出


您可以使用Kotlin扩展功能:

fun TabLayout.setupWithViewPager(viewPager: ViewPager2, labels: List<String>) {

    if (labels.size != viewPager.adapter?.itemCount)
        throw Exception("The size of list and the tab count should be equal!")

    TabLayoutMediator(this, viewPager,
        TabLayoutMediator.TabConfigurationStrategy { tab, position ->
            tab.text = labels[position]
        }).attach()
}
没有黑客,没有扩展,没有TabLayoutMediator 我在
implementation'com.google.android.material:material:1.2.0-alpha02'
上,在不需要TabLayoutMediator的情况下执行以下。 相反,我使用所描述的方法将TabLayout与ViewPager2链接。我还向github添加了一个工作示例。我想我已经将解决方案最小化为一个最小的工作示例。我会解释重要的部分

将元素添加到模板中 首先,我们需要将TabLayout和ViewPager2添加到布局中。我把它们放在一个线性布局和协调布局中,但是你当然可以做任何你喜欢的事情

<!-- 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,如下所示:

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连接到适配器 这应该非常简单。用户单击一个选项卡,我得到回调中的位置,我只需将适配器的当前项设置为该位置

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

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

我在com.google.android.material:material:1.2.1实现上运行我的,并且也没有使用tabLayoutMediator。首先,androidX中的TabLayout已经更改,因此请确保在导入语句中使用com.google.android.material.tabs.TabLayout。 以下是我对解决方案的其余实施: viewPager和TableLayout的Xml布局声明

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:background="@color/tan_background"
    android:orientation="vertical">

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tabs"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/viewpager"
        app:layout_anchor="@id/tabs"
        app:layout_anchorGravity="bottom"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>

我在另一个类中使用了片段适配器设置,如果选项卡标题来自
string.xml
,我将上下文传递给不同选项卡的构造函数 您可以将
片段
标题
放在一个
列表中
,然后通过
TabLayoutMediator
设置标题。它可以帮助您轻松地重新排序、删除或添加新片段

class MyFragment : Fragment() {

    override fun onCreateView(...): View? {
        ...

        TabLayoutMediator(tabLayout, viewPager) { tab, position ->
            tab.text = pagerAdapter.getTabTitle(position)
        }.attach()
    }

    private inner class PagerAdapter(fa: FragmentActivity) : FragmentStateAdapter(fa) {
        val pages = listOf(
            Pair(HomeFragment.newInstance(), R.string.home),
            Pair(GraphFragment.newInstance(), R.string.graph),
            Pair(SettingFragment.newInstance(), R.string.setting),
        )

        override fun createFragment(position: Int): Fragment {
            return pages[position].first
        }

        override fun getItemCount(): Int {
            return pages.count()
        }

        fun getTabTitle(position: Int): String {
            return getString(pages[position].second)
        }
    }
}

如果您是用JAVA编写代码。您可以为viewPager2使用以下适配器:

public class ViewPagerAdapter extends FragmentStateAdapter {
  private static final int CARD_ITEM_SIZE = 10;
  public ViewPagerAdapter(@NonNull FragmentActivity fragmentActivity) {
    super(fragmentActivity);
  }
  @NonNull @Override public Fragment createFragment(int position) {
    return CardFragment.newInstance(position);
  }
  @Override public int getItemCount() {
    return CARD_ITEM_SIZE;
  }
}
在main活动中,您需要与以下内容相关联:

@Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    viewPager = findViewById(R.id.view_pager);
    tabLayout = findViewById(R.id.tabs);
    viewPager.setAdapter(new ViewPagerAdapter(this));
    new TabLayoutMediator(tabLayout, viewPager,
        new TabLayoutMediator.TabConfigurationStrategy() {
          @Override public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
            tab.setText("Tab " + (position + 1));
          }
        }).attach();
  }
}

确保在设置适配器后使用TabLayoutMediator
查看页面2

TabLayoutMediator(tab_layout, view_pager2) { tab, position ->
                tab.text = fragmentList[position].second  // here u can modify you text..
            }.attach()

使用此TabLayoutMediator的代码如下:TabLayoutMediator(tabLayout,viewPager2){tab,position->viewPager2.setCurrentItem(tab.position,true)if(position==1)tab.setText(“Test2”)if(position==0)tab.setText(“Test1”)}.attach()
任何阅读本文的人都应该仔细检查他们应用程序的材质库版本
TabLayoutMediator
出现在
implementation'com.google.android.material:material:1.1.0-alpha08'
中,但android studio默认为我导入了版本
1.0.0
,而我没有这个版本。我如何在TabLayout上设置点(如旋转木马),而不是在选项卡中设置数字?
viewPager.setCurrentItem>(tab.position,true)
是不必要的,它会导致选择第二个选项卡,并始终滑动页面!@ericn你说得对,设置当前项目是自行滑动的。任何阅读此内容的人都应该仔细检查其应用程序的材料库版本。此版本对我有效,但android studio默认导入了1.0.0版,但它不适用于我公元this@anshsachdeva同样,我在com.google.android.material:material:1.0.0-alpha08,com.google.android.material:material:1.0.0-alpha09中找不到TabLayoutMediator类。@Seyid KananBagirov它出现在1中的实现“com.google.android.material:material:1.1.0-alpha08”(注意版本1.1.0-alpha08,而不是1.0.0)。
pa.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
    @Override
    public void onPageSelected(int position) {
        tabLayout.selectTab(tabLayout.getTabAt(position));
    }
});
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:background="@color/tan_background"
    android:orientation="vertical">

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tabs"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/viewpager"
        app:layout_anchor="@id/tabs"
        app:layout_anchorGravity="bottom"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Set the content of the activity to use the activity_main.xml layout file
        setContentView(layout.activity_main);

        // Find the view pager that will allow the user to swipe between fragments
        ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);

        // Create an adapter that knows which fragment should be shown on each page
        SimpleFragmentPagerAdapter adapter = new SimpleFragmentPagerAdapter(this,getSupportFragmentManager());

        // Set the adapter onto the view pager
        viewPager.setAdapter(adapter);

        // Find the tab layout that shows the tabs
        TabLayout tabLayout = findViewById(R.id.tabs);

        // Connect the tab layout with the view pager. This will
        //   1. Update the tab layout when the view pager is swiped
        //   2. Update the view pager when a tab is selected
        //   3. Set the tab layout's tab names with the view pager's adapter's titles
        //      by calling onPageTitle()
        tabLayout.setupWithViewPager(viewPager);
    }
}
class MyFragment : Fragment() {

    override fun onCreateView(...): View? {
        ...

        TabLayoutMediator(tabLayout, viewPager) { tab, position ->
            tab.text = pagerAdapter.getTabTitle(position)
        }.attach()
    }

    private inner class PagerAdapter(fa: FragmentActivity) : FragmentStateAdapter(fa) {
        val pages = listOf(
            Pair(HomeFragment.newInstance(), R.string.home),
            Pair(GraphFragment.newInstance(), R.string.graph),
            Pair(SettingFragment.newInstance(), R.string.setting),
        )

        override fun createFragment(position: Int): Fragment {
            return pages[position].first
        }

        override fun getItemCount(): Int {
            return pages.count()
        }

        fun getTabTitle(position: Int): String {
            return getString(pages[position].second)
        }
    }
}
public class ViewPagerAdapter extends FragmentStateAdapter {
  private static final int CARD_ITEM_SIZE = 10;
  public ViewPagerAdapter(@NonNull FragmentActivity fragmentActivity) {
    super(fragmentActivity);
  }
  @NonNull @Override public Fragment createFragment(int position) {
    return CardFragment.newInstance(position);
  }
  @Override public int getItemCount() {
    return CARD_ITEM_SIZE;
  }
}
@Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    viewPager = findViewById(R.id.view_pager);
    tabLayout = findViewById(R.id.tabs);
    viewPager.setAdapter(new ViewPagerAdapter(this));
    new TabLayoutMediator(tabLayout, viewPager,
        new TabLayoutMediator.TabConfigurationStrategy() {
          @Override public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
            tab.setText("Tab " + (position + 1));
          }
        }).attach();
  }
}
TabLayoutMediator(tab_layout, view_pager2) { tab, position ->
                tab.text = fragmentList[position].second  // here u can modify you text..
            }.attach()