Android : Tabs + ViewPager "Swipe-able Tabs, FTW"

Dalam Tab menggunakan Fragmen dan kemudian bagaimana menerapkan halaman menggesekkan menggunakan ViewPager. Dalam posting ini, saya akan membawa dua nugget bersama-sama dan menunjukkan cara untuk menerapkan Swipe-able Tabs,  (yaitu berpindah antar tab menggunakan gerakan menggesek).

Catatan : Pada saat posting ini, tidak ada cara untuk menerapkan MapView sebagai fragmen, yang mungkin menempatkan spanner dalam bekerja jika Anda berpikir tentang menggunakan pola ini UI dengan MapView.

Untuk menerapkan Tabs & ViewPager, menggunakan fragmen pada perangkat yang menjalankan Android 2.1 atau lebih tinggi, Anda akan perlu menyertakan Kompatibilitas Android perpustakaan. Dalam contoh saya, saya menggunakan library Kompatibilitas v4.


Step-By-Step
  1. Define the Tab ViewPager layout
  2. Define the PagerAdapter
  3. Define the Tab FragmentActivity.
Kode

Tata letak ViewPager Tab


Tab ViewPager tata letak (tabs_viewpager_layout.xml) mendeklarasikan TabHost dan pemandangan TabWidget anak seperti biasa. Untuk implementasi ini, alih-alih memiliki FrameLayout dummy untuk menahan konten, kita mendefinisikan ViewPager (android.support.v4.view.ViewPager)

<?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">
    <TabHost
        android:id="@android:id/tabhost"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        >
        <LinearLayout
            android:orientation="vertical"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            >
            <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="0dp"
                android:layout_weight="1"
                />
        </LinearLayout>
    </TabHost>
</LinearLayout>
Define the PagerAdapter
As explained in the previous post, Page Swiping using ViewPager , the PagerAdapter is responsible for creating/returning the appropriate Fragment to the ViewPager.   The declaration of PageAdapter is unchanged from the previous post.

package com.andy.fragments.viewpager;
import java.util.List;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
/**
 * The <code>PagerAdapter</code> serves the fragments when paging.
 * @author mwho
 */
public class PagerAdapter extends FragmentPagerAdapter {
    private List<Fragment> fragments;
    /**
     * @param fm
     * @param fragments
     */
    public PagerAdapter(FragmentManager fm, List<Fragment> fragments) {
        super(fm);
        this.fragments = fragments;
    }
    /* (non-Javadoc)
     * @see android.support.v4.app.FragmentPagerAdapter#getItem(int)
     */
    @Override
    public Fragment getItem(int position) {
        return this.fragments.get(position);
    }
    /* (non-Javadoc)
     * @see android.support.v4.view.PagerAdapter#getCount()
     */
    @Override
    public int getCount() {
        return this.fragments.size();
    }
}

Define the Tab FragmentActivity

The Tab FragmentActivity is a modified version Tab FragmentActivity I posted about in, Tabs, The Fragment Way . Thankfully, using ViewPager requires less code =)
*Disclaimer: The redundant lines of code are there to illustrate the minimal amount of changes required to implement view paging from the stock Tab implementation*
Change 1 : As per the normal initialisation of Tabs, we create Tahhost.TabSpec instances for each tab.  In this implementation, we simple just add it to the TabHost (line 139) without having to detach fragments.
Change 2 : Initialise the ViewPager . From line 099, we instantiate the Fragments and pass them to the ViewPager via the PagerAdapter . The order that the Fragments are supplied in the List will determine their tab order.
Change 3 : Tab FragmentActivity to implement ViewPager.OnPageChangeListener interface . In order to handle page “swipe” events, our Tab FragmentActivity needs to implement the ViewPager.OnPageChangeListener interface. For our purpose we only really need to implement the onPageSelect() method (Line 168). Simply, when the page is selected (paged), it’s associated Tab is selected.
Change 4 : Modify the onTabChanged() method. Similarly to Change 3 , when a tab is select (and therefore becomes selected), we set the appropriate Fragment via the ViewPager mViewPager (Line 148).

package com.andy.fragments.tabs;
import java.util.HashMap;
import java.util.List;
import java.util.Vector;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.widget.TabHost;
import android.widget.TabHost.TabContentFactory;
import com.andy.R;
import com.andy.fragments.viewpager.PagerAdapter;
/**
 * The <code>TabsViewPagerFragmentActivity</code> class implements the Fragment activity that maintains a TabHost using a ViewPager.
 * @author mwho
 */
public class TabsViewPagerFragmentActivity extends FragmentActivity implements TabHost.OnTabChangeListener, ViewPager.OnPageChangeListener {
    private TabHost mTabHost;
    private ViewPager mViewPager;
    private HashMap<String, TabInfo> mapTabInfo = new HashMap<String, TabsViewPagerFragmentActivity.TabInfo>();
    private PagerAdapter mPagerAdapter;
    /**
     *
     * @author mwho
     * Maintains extrinsic info of a tab's construct
     */
    private class TabInfo {
         private String tag;
         private Class<?> clss;
         private Bundle args;
         private Fragment fragment;
         TabInfo(String tag, Class<?> clazz, Bundle args) {
             this.tag = tag;
             this.clss = clazz;
             this.args = args;
         }
    }
    /**
     * A simple factory that returns dummy views to the Tabhost
     * @author mwho
     */
    class TabFactory implements TabContentFactory {
        private final Context mContext;
        /**
         * @param context
         */
        public TabFactory(Context context) {
            mContext = context;
        }
        /** (non-Javadoc)
         * @see android.widget.TabHost.TabContentFactory#createTabContent(java.lang.String)
         */
        public View createTabContent(String tag) {
            View v = new View(mContext);
            v.setMinimumWidth(0);
            v.setMinimumHeight(0);
            return v;
        }
    }
    /** (non-Javadoc)
     * @see android.support.v4.app.FragmentActivity#onCreate(android.os.Bundle)
     */
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Inflate the layout
        setContentView(R.layout.tabs_viewpager_layout);
        // Initialise the TabHost
        this.initialiseTabHost(savedInstanceState);
        if (savedInstanceState != null) {
            mTabHost.setCurrentTabByTag(savedInstanceState.getString("tab")); //set the tab as per the saved state
        }
        // Intialise ViewPager
        this.intialiseViewPager();
    }
    /** (non-Javadoc)
     * @see android.support.v4.app.FragmentActivity#onSaveInstanceState(android.os.Bundle)
     */
    protected void onSaveInstanceState(Bundle outState) {
        outState.putString("tab", mTabHost.getCurrentTabTag()); //save the tab selected
        super.onSaveInstanceState(outState);
    }
    /**
     * Initialise ViewPager
     */
    private void intialiseViewPager() {
        List<Fragment> fragments = new Vector<Fragment>();
        fragments.add(Fragment.instantiate(this, Tab1Fragment.class.getName()));
        fragments.add(Fragment.instantiate(this, Tab2Fragment.class.getName()));
        fragments.add(Fragment.instantiate(this, Tab3Fragment.class.getName()));
        this.mPagerAdapter  = new PagerAdapter(super.getSupportFragmentManager(), fragments);
        //
        this.mViewPager = (ViewPager)super.findViewById(R.id.viewpager);
        this.mViewPager.setAdapter(this.mPagerAdapter);
        this.mViewPager.setOnPageChangeListener(this);
    }
    /**
     * Initialise the Tab Host
     */
    private void initialiseTabHost(Bundle args) {
        mTabHost = (TabHost)findViewById(android.R.id.tabhost);
        mTabHost.setup();
        TabInfo tabInfo = null;
        TabsViewPagerFragmentActivity.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab1").setIndicator("Tab 1"), ( tabInfo = new TabInfo("Tab1", Tab1Fragment.class, args)));
        this.mapTabInfo.put(tabInfo.tag, tabInfo);
        TabsViewPagerFragmentActivity.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab2").setIndicator("Tab 2"), ( tabInfo = new TabInfo("Tab2", Tab2Fragment.class, args)));
        this.mapTabInfo.put(tabInfo.tag, tabInfo);
        TabsViewPagerFragmentActivity.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab3").setIndicator("Tab 3"), ( tabInfo = new TabInfo("Tab3", Tab3Fragment.class, args)));
        this.mapTabInfo.put(tabInfo.tag, tabInfo);
        // Default to first tab
        //this.onTabChanged("Tab1");
        //
        mTabHost.setOnTabChangedListener(this);
    }
    /**
     * Add Tab content to the Tabhost
     * @param activity
     * @param tabHost
     * @param tabSpec
     * @param clss
     * @param args
     */
    private static void AddTab(TabsViewPagerFragmentActivity activity, TabHost tabHost, TabHost.TabSpec tabSpec, TabInfo tabInfo) {
        // Attach a Tab view factory to the spec
        tabSpec.setContent(activity.new TabFactory(activity));
        tabHost.addTab(tabSpec);
    }
    /** (non-Javadoc)
     * @see android.widget.TabHost.OnTabChangeListener#onTabChanged(java.lang.String)
     */
    public void onTabChanged(String tag) {
        //TabInfo newTab = this.mapTabInfo.get(tag);
        int pos = this.mTabHost.getCurrentTab();
        this.mViewPager.setCurrentItem(pos);
    }
    /* (non-Javadoc)
     * @see android.support.v4.view.ViewPager.OnPageChangeListener#onPageScrolled(int, float, int)
     */
    @Override
    public void onPageScrolled(int position, float positionOffset,
            int positionOffsetPixels) {
        // TODO Auto-generated method stub
    }
    /* (non-Javadoc)
     * @see android.support.v4.view.ViewPager.OnPageChangeListener#onPageSelected(int)
     */
    @Override
    public void onPageSelected(int position) {
        // TODO Auto-generated method stub
        this.mTabHost.setCurrentTab(position);
    }
    /* (non-Javadoc)
     * @see android.support.v4.view.ViewPager.OnPageChangeListener#onPageScrollStateChanged(int)
     */
    @Override
    public void onPageScrollStateChanged(int state) {
        // TODO Auto-generated method stub
    }
} 
Sumber @ thepseudocoder dot wordpress dot com





0 Response to " Android : Tabs + ViewPager "Swipe-able Tabs, FTW" "

Posting Komentar