Fragments實現選項卡功能

        最近要實現一個選項卡的效果,類似於騰訊新聞客戶端,點擊屏幕下方的tab選項切換頁面,效果圖如下:

        其實這就是一個典型的選項卡,可以通過使用TabHost組件方便的在窗口上放置多個標籤頁。一般在使用TabHost的時候,都需要activity繼承TabActivity,然而TabActivity已經不推薦使用了,官方文檔如下:



        很顯然,新的應用應該使用Fragments取代TabActivity,既然如此,那就用Fragments實現好了,步驟如下:

      (1)新建activity_main.xml文件,其中TabWidget代表選項卡的標籤條,fragment代表具體每個頁面。

<TabHost 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:id="@android:id/tabhost"
    tools:context=".MainActivity" >
	
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        >
        <TabWidget 
            android:id="@android:id/tabs"
            android:layout_width="match_parent"
            android:layout_height="55dip"
            android:layout_alignParentBottom="true"
            >
        </TabWidget>
        
        <FrameLayout 
            android:id="@android:id/tabcontent"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_above="@android:id/tabs"
            >
            <fragment 
                android:name="com.stefanli.bct.Tab1Fragment"
                android:id="@+id/tab1"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                />
            <fragment 
                android:name="com.stefanli.bct.Tab2Fragment"
                android:id="@+id/tab2"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                />
            <fragment 
                android:name="com.stefanli.bct.Tab3Fragment"
                android:id="@+id/tab3"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                />
            <fragment 
                android:name="com.stefanli.bct.Tab4Fragment"
                android:id="@+id/tab4"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                />
        </FrameLayout>
    </RelativeLayout>

</TabHost>

      (2)創建Fragment,其中R.layout.tab1即爲該選項頁面的佈局文件,具體不再給出。

public class Tab1Fragment extends Fragment {
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		return inflater.inflate(R.layout.tab1, container, false);
	}
}

      (3)自定義tab樣式,佈局文件和自定義View如下:(PS:自定義是爲了更好控制tab樣式,滿足各種效果,系統自帶的很醜而且很難調整)。

        tab_menu.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:background="@color/tab_bg"
    tools:context=".MainActivity" >

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true" >

        <ImageView
            android:id="@+id/icon"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:src="@drawable/tab1_selected" />

        <TextView
            android:id="@+id/content"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/icon"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="3dip"
            android:text="@string/tab_session"
            android:textColor="@color/tab_text_nor_color"
            android:textSize="12sp" />
    </RelativeLayout>

</RelativeLayout>

        自定義控件TabView如下:

/**
 * 自定義TabHost的Tab樣式
 * @author Stefanli
 *
 */
public class TabView extends RelativeLayout {
	
	private ImageView mIcon;
	private TextView  mContent;
	private Context mContext;
	
	public TabView(Context context) {
		super(context);
		mContext = context;
		init();
	}
	
	public TabView(Context context, AttributeSet attrs) {
		super(context, attrs);
		mContext = context;
		init();
	}

	private void init(){
		LayoutInflater inflater=(LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.tab_menu, this);
		mIcon = (ImageView)findViewById(R.id.icon);
		mContent = (TextView)findViewById(R.id.content);
	}
	/**
	 * 設置圖標
	 * @param resId
	 *        圖標資源Id
	 */
	public void setIcon(int resId){
		mIcon.setImageResource(resId);
	}
	/**
	 * 設置內容文本資源
	 * @param resId
	 *        內容文本資源Id
	 */
	public void setContentText(int resId){
		mContent.setText(resId);
	}
	/**
	 * 判斷是否被選中
	 * @param isChecked
	 */
	public void setIsChecked(boolean isChecked){
		if(isChecked){
			mContent.setTextColor(getResources().getColor(R.color.tab_text_selected_color));
		}else{
			mContent.setTextColor(getResources().getColor(R.color.tab_text_nor_color));
		}
	}

}

      (4)最後一步,創建類繼承FragmentActivity,通過TabHost對象創建添加選項卡。

public class MainFragment extends FragmentActivity {
	
	private TabHost mTabHost;
	private TabWidget mTabWidget;
	private TabView mTabView;			//自定義Tab選項卡View
	private int[] mNormalIcon;			//未被選中圖標Id
	private int[] mSelectedIcon;		//被選中圖標Id
	private int[] mContentTextId;		//文本內容Id
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.activity_main);
		
		mNormalIcon = new int[]{R.drawable.tab1_normal,R.drawable.tab2_normal,R.drawable.tab3_normal,R.drawable.tab4_normal};
		mSelectedIcon = new int[]{R.drawable.tab1_selected,R.drawable.tab2_selected,R.drawable.tab3_selected,R.drawable.tab4_selected};
		mContentTextId = new int[]{R.string.tab_news,R.string.tab_order,R.string.tab_picture,R.string.tab_movie};
		
		mTabHost = (TabHost)findViewById(android.R.id.tabhost);
		mTabHost.setup();
		mTabWidget = mTabHost.getTabWidget();
		mTabWidget.setStripEnabled(false);
		mTabView = new TabView(this);
		
		mTabHost.addTab(mTabHost.newTabSpec(getString(mContentTextId[0])).setIndicator(new TabView(this)).setContent(R.id.tab1));  
		mTabHost.addTab(mTabHost.newTabSpec(getString(mContentTextId[1])).setIndicator(new TabView(this)).setContent(R.id.tab2));
		mTabHost.addTab(mTabHost.newTabSpec(getString(mContentTextId[2])).setIndicator(new TabView(this)).setContent(R.id.tab3));
		mTabHost.addTab(mTabHost.newTabSpec(getString(mContentTextId[3])).setIndicator(new TabView(this)).setContent(R.id.tab4));
		

		setTabStyle();
        
        mTabHost.setOnTabChangedListener(new OnTabChangeListener() {
			
			@Override
			public void onTabChanged(String arg0) {
				setTabStyle();
			}
		});
	}
	
	/**
	 * 設置tab選項卡樣式
	 */
	private void setTabStyle(){
		for (int i = 0; i < mTabWidget.getChildCount(); i++){
			mTabView = (TabView)mTabWidget.getChildAt(i);
			mTabView.setContentText(mContentTextId[i]);
			if (mTabHost.getCurrentTab() == i){
				//tab被選中狀態
				mTabView.setIsChecked(true);
				mTabView.setIcon(mSelectedIcon[i]);
			}else{
				//tab未被選中狀態
				mTabView.setIsChecked(false);
				mTabView.setIcon(mNormalIcon[i]);
			}			
		}
	}
	
}

        最終實現效果如下:


 

        因爲代碼實在太過簡單,不作過多分析,一看就懂。新手上路,請多指教~大笑


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章