Search code examples
androidandroid-viewpagerswipeandroid-2.2-froyofragment-tab-host

Tutorial to implement the use of TabHost in Android 2.2 + ViewPager and Fragments


A short tutorial for people like me who had some trouble finding a way to implement TabHost and ViewPager, including page swiping with fingers and tab click to change pages. The shown solution is compatible with Android versions 2.2+.

It includes Tabs initialization, ViewPager connected with Tabs and Page Scrolling management.

Its main peculiarity is the optimization for earlier versions of Android (Android 2.2 (Froyo), API version 8) and the simple implementation for different purposes.


Solution

  • The tutorial includes 4 classes and 2 layouts. It has been tested with an Android phone 2.2, and you can just copy & paste to try it.

    MainActivity.java (the main activity):

    package samples.tabhost.andreaoid.net;
    
    import java.util.ArrayList;
    import java.util.List;
    import android.os.Bundle;
    import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentActivity;
    import android.support.v4.view.ViewPager;
    import android.support.v4.view.ViewPager.OnPageChangeListener;
    import android.widget.TabHost;
    import android.widget.TabHost.OnTabChangeListener;
    
    public class MainActivity extends FragmentActivity implements OnTabChangeListener, OnPageChangeListener {
    
        MyPageAdapter pageAdapter;
        private ViewPager mViewPager;
        private TabHost mTabHost;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            mViewPager = (ViewPager) findViewById(R.id.viewpager);
    
            // Tab Initialization
            initialiseTabHost();
    
            // Fragments and ViewPager Initialization
            List<Fragment> fragments = getFragments();
            pageAdapter = new MyPageAdapter(getSupportFragmentManager(), fragments);
            mViewPager.setAdapter(pageAdapter);
            mViewPager.setOnPageChangeListener(MainActivity.this);
        }
    
        // Method to add a TabHost
        private static void AddTab(MainActivity activity, TabHost tabHost, TabHost.TabSpec tabSpec) {
            tabSpec.setContent(new MyTabFactory(activity));
            tabHost.addTab(tabSpec);
        }
    
        // Manages the Tab changes, synchronizing it with Pages
        public void onTabChanged(String tag) {
            int pos = this.mTabHost.getCurrentTab();
            this.mViewPager.setCurrentItem(pos);
        }
    
        @Override
        public void onPageScrollStateChanged(int arg0) {
        }
    
        // Manages the Page changes, synchronizing it with Tabs
        @Override
        public void onPageScrolled(int arg0, float arg1, int arg2) {
            int pos = this.mViewPager.getCurrentItem();
            this.mTabHost.setCurrentTab(pos);
        }
    
        @Override
            public void onPageSelected(int arg0) {
        }
    
        private List<Fragment> getFragments(){
            List<Fragment> fList = new ArrayList<Fragment>();
    
            // TODO Put here your Fragments
            MySampleFragment f1 = MySampleFragment.newInstance("Sample Fragment 1");
            MySampleFragment f2 = MySampleFragment.newInstance("Sample Fragment 2");
            MySampleFragment f3 = MySampleFragment.newInstance("Sample Fragment 3");
            fList.add(f1);
            fList.add(f2);
            fList.add(f3);
    
            return fList;
        }
    
        // Tabs Creation
        private void initialiseTabHost() {
            mTabHost = (TabHost) findViewById(android.R.id.tabhost);
            mTabHost.setup();
    
            // TODO Put here your Tabs
            MainActivity.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab1").setIndicator("Tab1"));
            MainActivity.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab2").setIndicator("Tab2"));
            MainActivity.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab3").setIndicator("Tab3"));
    
            mTabHost.setOnTabChangedListener(this);
        }
    }
    

    MyPageAdapter.java (fragment manager):

    package samples.tabhost.andreaoid.net;
    
    import java.util.List;
    import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentManager;
    import android.support.v4.app.FragmentPagerAdapter;
    
    public class MyPageAdapter extends FragmentPagerAdapter {
        private List<Fragment> fragments;
    
        public MyPageAdapter(FragmentManager fm, List<Fragment> fragments) {
            super(fm);
            this.fragments = fragments;
        }
    
        @Override
        public Fragment getItem(int position) {
            return this.fragments.get(position);
        }
    
        @Override
        public int getCount() {
            return this.fragments.size();
        }
    }
    

    MyTabFactory (tab manager):

    package samples.tabhost.andreaoid.net;
    
    import android.content.Context;
    import android.view.View;
    import android.widget.TabHost.TabContentFactory;
    
    public class MyTabFactory implements TabContentFactory {
    
        private final Context mContext;
    
        public MyTabFactory(Context context) {
            mContext = context;
        }
    
        public View createTabContent(String tag) {
            View v = new View(mContext);
            v.setMinimumWidth(0);
            v.setMinimumHeight(0);
            return v;
        }
    }
    

    MySampleFragment.java (the single fragment - included for demonstration purposes):

    package samples.tabhost.andreaoid.net;
    
    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.TextView;
    
    public class MySampleFragment extends Fragment {
    
        private static View mView;
    
        public static final MySampleFragment newInstance(String sampleText) {
            MySampleFragment f = new MySampleFragment();
    
            Bundle b = new Bundle();
            b.putString("bString", sampleText);
            f.setArguments(b);
    
            return f;
        }
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    
            mView = inflater.inflate(R.layout.sample_fragment, container, false);
            String sampleText = getArguments().getString("bString");
    
            TextView txtSampleText = (TextView) mView.findViewById(R.id.txtViewSample);
            txtSampleText.setText(sampleText);
    
            return mView;
        }
    }
    

    activity_main.xml:

    <RelativeLayout 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"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context=".MainActivity" >
    
        <TabHost
            android:id="@android:id/tabhost"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" >
            <LinearLayout
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical" >
                <TabWidget
                    android:id="@android:id/tabs"
                    android:orientation="horizontal"
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:layout_weight="0" />
                <FrameLayout
                    android:id="@android:id/tabcontent"
                    android:layout_width="0dp"
                    android:layout_height="0dp"
                    android:layout_weight="0" />
                <android.support.v4.view.ViewPager
                    android:id="@+id/viewpager"
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:layout_gravity="bottom" />
            </LinearLayout>
        </TabHost>
    </RelativeLayout>
    

    sample_fragment.xml (you can put here your fragment layout):

    <?xml version="1.0" encoding="utf-8"?>
    
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >
    
        <TextView
            android:id="@+id/txtViewSample"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignParentRight="true"
            android:layout_alignParentTop="true"
            android:text="" />
    
    </RelativeLayout>