Using TabLayouts in your Android app

So while making a sessions schedule for the open event app, I wanted to separate the sessions on the basis of the days they are scheduled for to improve the visual clarity. So to do this I had various approaches like add a filter to separate by date or add checkboxes to show only checked dates but I though they’d look ugly. Instead the best option was to add tabs in a fragment with a viewpager to scroll within them : It looks appealing, has simple and clean UI, easier to implement with the new design library. So, naturally I opted for using the Tablayout from the design Library.

Earlier, when the Support design library was not introduce, it was really a tedious job to add it to our app since we had to extend Listeners to check for tab changes and we had to manually open fragments when a tab was selected or unselected or even when it was reselected. Essentially this meant a lot of errors and memory leaks. In the design library we essentially need to add tablayout and a viewpager to our layout like this :

<android.support.design.widget.AppBarLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.TabLayout
        android:id="@+id/tabLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabGravity="fill"
        app:tabMode="fixed"
        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>

Next in our activity/ fragment, we can just inflate this view and create an adapter for the viewpager extending a FragmentPagerAdapter:

public class OurAdapter extends FragmentPagerAdapter {
    private final List<Fragment> mFragmentList = new ArrayList<>();
    private final List<String> mFragmentTitleList = new ArrayList<>();

    public ScheduleViewPagerAdapter(FragmentManager manager) {
        super(manager);
    }

    @Override
    public Fragment getItem(int position) {
        return mFragmentList.get(position);
    }

    @Override
    public int getCount() {
        return mFragmentList.size();
    }

    public void addFragment(Fragment fragment, String title, int day) {

        mFragmentList.add(fragment);
        mFragmentTitleList.add(title);
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return mFragmentTitleList.get(position);
    }
}

Now I had to make dynamic number of tabs, since I wanted the app to customisable on the number of days listed in the json downloaded from the server. So, I made some changes in the traditional code. This is what we do in our activity/fragment’s onCreate/OnCreatView :

viewPager = (ViewPager) view.findViewById(R.id.viewpager);

for (int i = 0; i < daysofEvent; i++) {
    adapter.addFragment(new DayScheduleFragment(),title, dayNo);
}

viewPager.setAdapter(adapter);
scheduleTabLayout = (TabLayout) view.findViewById(R.id.tabLayout);
scheduleTabLayout.setupWithViewPager(viewPager);

This is it. Now we have a basic working tablayout in a viewpager. This also has the capability to change according to the number of days specified in the json we have written.

Earlier without the design library, we would have to even add switch cases in the FragmentPagerAdapter like this :

public class OurAdapter extends FragmentPagerAdapter {
 
 public TabsPagerAdapter(FragmentManager fm) {
    super(fm);
 }
 
 @Override
 public Fragment getItem(int index) {
 
 switch (index) {
 case 0:
    return new FirstFragment();
 case 1:
    return new SecondFragment();
 case 2:
    return new ThirdFragment();
 }
 
 return null;
 }

Then we would have to override methods to listen to activities in tabs :

@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}

@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
// on tab selected
// show respected fragment view
   viewPager.setCurrentItem(tab.getPosition());
}

@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}

And more code to listen for swiping within tabs in a viewpager:

/**
* on swiping the viewpager make respective tab selected
**/
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {

@Override
public void onPageSelected(int position) {

// on changing the page
// make respected tab selected
actionBar.setSelectedNavigationItem(position);
}

@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}

@Override
public void onPageScrollStateChanged(int arg0) {
}
});

You see how easy this got with the inclusion of TabLayout.

Now for the final product I made after inflating the fragments and adding recyclerviews for the schedule, I got this :

Swipable tabs

I urge you to try swipable tabs in your app as well. Adios till next time.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.