Android Material Design - ViewPager with Tabs using Design Support Library

    With with the appearance of Android Lollipop, a lot of new features released by Google. Along with that, support libraries system was published. The new Design Support Library was also included in the support repository. This new Android Design Support library provides a lot of new UI components like snackbars, floating action buttons and of-course it significantly improves the implementation of Android Tabs.
    Previously, to make tabs in Android, we will use PagerTabStrip widget in Android SDK or more flexible,  external libraries like PagerSlidingTabStrip, PagerIndicator,... are not a bad choice. But now with API 21 onwards, ActionBar has been deprecated. An alternative way to make tabs with full backward support was to use SlidingTabLayout and SlidingTabStrip classes. But now with Android Design Support Library, making swiping tabs has become even more simple. In this Android Tabs example, let's explore the power of new design support library.
Application Output
    In this post, I will prensent the way to make a simple project having a ViewPager with tab bar at top of screen with this new style. Now, create a new Android Project (min-sdk I use is 14).
    Before start, including these libraries in the dependencies section of your local build.gradle file (often located in 'app' module):
compile 'com.android.support:appcompat-v7:22.2.0'
compile 'com.android.support:design:22.2.0' // design support library
    We must customizing a theme based on "Theme.AppCompat.Light.NoActionBar" to use Material Design style. Open your styles.xml file and put this code:
   

Create a main activity to run

    As noted above, instead of ActionBar, we use Toolbar, and TabLayout is widget to make tab bar. Activity layout like this:
    In programmatically code, when user click at each tab, ViewPager will switch to corresponding screen, so add a TabLayout.OnTabSelectedListener method to handle this action:
private TabLayout.OnTabSelectedListener onTabSelectedListener(final ViewPager pager) {
        return new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                pager.setCurrentItem(tab.getPosition());
            }

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

            }

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

            }
        };
    }
    Set "page changed listener" for ViewPager and use above method with these lines (often put after set ViewPager adapter):
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.setOnTabSelectedListener(onTabSelectedListener(viewPager));
    Now, we have full code for activity and styles resources:
package devexchanges.info.viewpagertabsmd;

import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;

public class MainActivity extends AppCompatActivity {

    private final int numOfPages = 4; //viewpager has 4 pages
    private final String[] pageTitle = {"Food", "Movie", "Shopping", "Travel"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);

        for (int i = 0; i < numOfPages; i++) {
            tabLayout.addTab(tabLayout.newTab().setText(pageTitle[i]));
        }

        //set gravity for tab bar
        tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);

        final ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
        final PagerAdapter adapter = new PagerAdapter
                (getSupportFragmentManager(), numOfPages);

        viewPager.setAdapter(adapter);
        viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
        tabLayout.setOnTabSelectedListener(onTabSelectedListener(viewPager));
    }

    private TabLayout.OnTabSelectedListener onTabSelectedListener(final ViewPager pager) {
        return new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                pager.setCurrentItem(tab.getPosition());
            }

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

            }

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

            }
        };
    }
}


    

    

    


Create a ViewPager adapter

    We can customizing a ViewPager adapter based on FragmentStatePagerAdapter or FragmentPagerAdapter, declaring number of pages in it's constructor simple like this:
package devexchanges.info.viewpagertabsmd;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;

public class PagerAdapter extends FragmentStatePagerAdapter {
    int numOfTabs;

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

    @Override
    public Fragment getItem(int position) {

       return TabFragment.getInstance(position);
    }

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

Create Fragments (Pages)

    Okey, I use a "mutual code" for all pages (Fragment), based on each page position, it's content has been changed! Programmatically code:
package devexchanges.info.viewpagertabsmd;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

public class TabFragment extends Fragment {

    private int position;
    private TextView content;
    private ImageView image;

    public static Fragment getInstance(int position) {
        TabFragment f = new TabFragment();
        Bundle args = new Bundle();
        args.putInt("position", position);
        f.setArguments(args);
        return f;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //get data from Argument
        position = getArguments().getInt("position");
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.tab_fragment, container, false);
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        image = (ImageView) view.findViewById(R.id.image);
        content = (TextView) view.findViewById(R.id.textView);
        setContentView();
    }

    private void setContentView() {
        if (position == 0) {
            //food fragment
            image.setImageResource(R.mipmap.food);
            content.setText("This is Food Fragment");
        } else if (position == 1) {
            //movie fragment
            image.setImageResource(R.mipmap.movie);
            content.setText("This is Movie Fragment");
        } else if (position == 2) {
            //shopping fragment
            image.setImageResource(R.mipmap.shopping);
            content.setText("This is Shopping Fragment");
        } else {
            //travel fragment
            image.setImageResource(R.mipmap.travel);
            content.setText("This is Travel Fragment");
        }
    }
}
    And it's layout:

Running Application


Coming here, we have completed code, run this application (app module), we will see our result similar with this:


Share


Previous post
« Prev Post
Next post
Next Post »