简体   繁体   中英

Custom Tab layout with ViewPager2

I am trying to use custom tabs for my ViewPager2 via the TabLayout.Tab.setCustomView method. But it doesn't work.

Here is a code snippet from my Activity for preparing the ViewPager2 with a TabLayout :

@Override
protected void onCreate(Bundle savedInstanceState)
{
   ...
   
   mMyViewPager2 = findViewById(R.id.view_pager);
   mMyViewPager2.setAdapter(new MyPagerAdapter(this));
   mMyTabLayout = findViewById(R.id.media_tab);
   new TabLayoutMediator(mMyTabLayout, mMyViewPager2, myTabHandler).attach();
}

private class MyPagerAdapter extends FragmentStateAdapter
{
   ...
}

And here is the code snippet for my TabLayoutMediator.TabConfigurationStrategy (also inside my Activity ):

private TabLayoutMediator.TabConfigurationStrategy myTabHandler = new TabLayoutMediator.TabConfigurationStrategy()  
{
    private TextView tabTitle;
    private TextView tabSubtitle;

    @Override
    public void onConfigureTab(@NonNull TabLayout.Tab tab, int position)
    {
        View tabView = LayoutInflater.from(MyActivity.this).inflate(R.layout.tab_layout, null, false);

        tabTitle    = tabView.findViewById(R.id.tab_title);
        tabSubtitle = tabView.findViewById(R.id.tab_subtitle);
        
        tabTitle.setText("Title" + (position + 1));
        tabSubtitle.setText("Subtitle" + (position + 1));

        tab.setCustomView(tabView);
    }
}

But with the above setup, the tabs remain blank.

I've also tried the following approach in my TabConfigurationStrategy (from this post ); but it doesn't work, either:

FrameLayout frameLayout = new FrameLayout(MyActivity.this);
frameLayout.addView(tabView);

I'd like to know what is wrong with my code, and how can I correct it to show custom tab layouts with ViewPager2 .

From setCustomView() documentation:

If the provided view contains a TextView with an ID of text1 then that will be updated with the value given to setText(CharSequence)

So try changing the tabTitle's Id to "@android:id/text1" .

Now for the subtitle, I am not certain of this. Using "@android:id/text2" might be worth a try. Note: "@android:id/text2" exists.

Nevertheless, you can apply your own layout declaratively to the TabItems using android:layout="" , thus negating the need for you to do it programmatically. There is an example of the declarative version in the TabLayout documentation . So I believe something like this would work:

<TabLayout
        ...>

     <TabItem
            ....
             android:layout="@layout/linearLayout_tabitem_1"/>

     <TabItem 
             ....
             android:layout="@layout/linearLayout_tabitem_2"/>

 </TabLayout>

You can define the the title of tabs in your pagerAdapter itself.

@Override
protected void onCreate(Bundle savedInstanceState)
{
   ...
   MyPagerAdapter adapter = new MyPagerAdapter(this, getSupportFragmentManager() , 2);
   mMyTabLayout = findViewById(R.id.media_tab);
   mMyViewPager2 = findViewById(R.id.view_pager);
   pager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(mMyTabLayout));
   mMyViewPager2.setAdapter(adapter);
   mMyTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            mMyViewPager2.setCurrentItem(tab.getPosition());
            setTabView(tab.getPosition());
        }

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

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

private void setTabView(int index) {

    TabLayout.Tab tab = mMyTabLayout.getTabAt(index);
    tab.setCustomView(R.layout.tab_layout);
    ((TextView) tab.getCustomView().findViewById(R.id.tabSubtitle)).setText("Subtitle" + (position + 1));
}



private class MyPagerAdapter extends FragmentStatePagerAdapter
{
   private Context mContext;
   private int mCount;

    public MyPagerAdapter(Context context, FragmentManager fm , int count) {
        super(fm);
        mContext = context;
        mCount = count;
        notifyDataSetChanged();

    @Override
    public Fragment getItem(int position) {
        if (position == 0)
            return someFragment();
        else if (position == 1)
            return someOtherFragment(); 



    }
    @Override
    public int getCount() {
        return mCount;
    }
    @Override
    public CharSequence getPageTitle(int position) {
    // Generate title based on item position
        switch (position) {
            case 0:
                return "Title" + position+1;
            case 1:
                return "Title" + position+1;
            default:
                return null;
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM