Jacques Krause
Jacques Krause

Reputation: 5569

TabLayout tabs text not displaying

I am using TabLayout inside a Fragment to display three fixed tabs and the tabs are working but it doesn't show the tab text even after I set the app:tabTextColor attribute in the layout it's still not visible.

NewFragment.java

public class NewFragment extends Fragment {

private RecyclerView mRecyclerView;
private RecyclerView.LayoutManager mLayoutManager;
private RecyclerView.Adapter mAdapter;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    View inflatedView = inflater.inflate(R.layout.new_fragment, container, false);

    TabLayout tabLayout = (TabLayout) inflatedView.findViewById(R.id.tabLayout);
    tabLayout.addTab(tabLayout.newTab().setText("Tab 1"));
    tabLayout.addTab(tabLayout.newTab().setText("Tab 2"));
    tabLayout.addTab(tabLayout.newTab().setText("Tab 3"));
    final ViewPager viewPager = (ViewPager) inflatedView.findViewById(R.id.viewpager);

    LinearLayoutManager mLayoutManager = new LinearLayoutManager(getActivity());
    mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);

    viewPager.setAdapter(new PagerAdapter(getFragmentManager(), tabLayout.getTabCount()));
    viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
    tabLayout.setupWithViewPager(viewPager);
    tabLayout.setTabMode(TabLayout.MODE_FIXED);
    tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {

        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            viewPager.setCurrentItem(tab.getPosition());
        }

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

        }

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

        }
    });

    return inflatedView;
}

public class PagerAdapter extends FragmentStatePagerAdapter {
    int mNumOfTabs;

    public PagerAdapter(FragmentManager fm, int NumOfTabs) {
        super(fm);
        this.mNumOfTabs = NumOfTabs;
    }

    @Override
    public Fragment getItem(int position) {

        switch (position) {
            case 0:
                return new FragmentTab();
            case 1:
                return new FragmentTab();
            case 2:
                return new FragmentTab();
            default:
                return null;
        }
    }

    @Override
    public int getCount() {
        return mNumOfTabs;
    }
}
}

newfragment.xml

<android.support.design.widget.AppBarLayout 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"
tools:context=".NewFragment">

<android.support.design.widget.TabLayout
    android:id="@+id/tabLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:tabMode="fixed"
    app:tabTextColor="#ffffff"
    app:tabGravity="fill"
    app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>

<android.support.v4.view.ViewPager
    android:id="@+id/viewpager"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@android:color/white"/>

</android.support.design.widget.AppBarLayout>

Upvotes: 81

Views: 48408

Answers (5)

Rahul Kumar
Rahul Kumar

Reputation: 51

tabLayout!!.setupWithViewPager(viewpager) check this line it's pointing to right viewpager or not.

Upvotes: 0

Kamyar Miremadi
Kamyar Miremadi

Reputation: 179

I wanted to define TabItem in XML instead of doing it programmatically. As you mentioned, this setupWithViewPager() call resets the text and icon of the tab items to null( It uses the same tab object, just resets its content). I used your approach but made it more reusable. Here is my code:

public class TabLayoutUtil {
    public static void setupTabLayoutWithViewPager(TabLayout tabLayout, ViewPager viewPager) {
        ArrayList<Pair<CharSequence, Drawable>> tabsContentCopy= new ArrayList<>();
        for (int i = 0; i < tabLayout.getTabCount(); i++) {
            TabLayout.Tab tab = tabLayout.getTabAt(i);
            tabsContentCopy.add(new Pair<>(tab != null ? tab.getText() : null, tab != null ? tab.getIcon() : null));
        }
        tabLayout.setupWithViewPager(viewPager);
        for (int i = 0; i < tabLayout.getTabCount(); i++) {
            if (i<tabsContentCopy.size()) {
                tabLayout.getTabAt(i).setText(tabsContentCopy.get(i).first);
                tabLayout.getTabAt(i).setIcon(tabsContentCopy.get(i).second);
            }
        }
    }
}

Upvotes: 0

earthw0rmjim
earthw0rmjim

Reputation: 19417

The problem is you're calling setupWithViewPager() after setting up your tabs with the addTab() calls, effectively overwriting them.

From the documentation of TabLayout regarding setupWithViewPager():

The tabs displayed in this layout will be populated from the ViewPager adapter's page titles.

If you would like to use your TabLayout with a ViewPager, you should override getPageTitle() in your PagerAdapter (and remove the addTab() calls, they are redundant).

For example:

public class ExamplePagerAdapter extends FragmentStatePagerAdapter {

    // tab titles
    private String[] tabTitles = new String[]{"Tab1", "Tab2", "Tab3"};

    public ExamplePagerAdapter(FragmentManager fm) {
        super(fm);
    }

    // overriding getPageTitle()
    @Override
    public CharSequence getPageTitle(int position) {
        return tabTitles[position];
    }

    @Override
    public Fragment getItem(int position) {
        switch (position) {
            case 0:
                return new Tab1Fragment();
            case 1:
                return new Tab2Fragment();
            case 2:
                return new Tab3Fragment();
            default:
                throw new RuntimeException("Invalid tab position");
        }
    }

    @Override
    public int getCount() {
        return tabTitles.length;
    }

    // ...
}

Upvotes: 154

Irfandi D. Vendy
Irfandi D. Vendy

Reputation: 1004

I'm using Kotlin and have spent an hour to find the bugs with this code.

var viewPager: ViewPager = view.findViewById(R.id.viewPager)

...

adapter = TabAdapter(fragmentManager!!)
adapter.addFragment(Fragment1(), "Fragment 1")
adapter.addFragment(Fragment2(), "Fragment 2")

viewPager.adapter = adapter

tabLayout.setupWithViewPager(viewpager)

I can compile this with no error, but the tab title is not showing until I realize the viewpager I assigned to the tabLayout is not viewPager (notice the capitalize 'P'). It's not producing error because kotlin will find any matching layout id, in this case "viewpager" which is a ViewPager but on another view.

Upvotes: 2

Hatem Badawi
Hatem Badawi

Reputation: 546

i added tab text and icon for each tab after calling tabs.setupWithViewPager(viewPager)

    viewPager.setAdapter(new MyViewAdapter(getSupportFragmentManager()));
    TabLayout tabs=(TabLayout) findViewById(R.id.tabs);
    tabs.setupWithViewPager(viewPager);
    tabs.getTabAt(0).setIcon(R.drawable.icon1);
    tabs.getTabAt(1).setIcon(R.drawable.icon2);
    tabs.getTabAt(0).setText(getResources().getText(R.string.tab1));
    tabs.getTabAt(1).setText(getResources().getText(R.string.tab2));

Upvotes: 12

Related Questions