Android利用Fragment實現Tab佈局

Android利用Fragment實現Tab佈局

在上一篇中,我們通過ViewPager實現了Tab佈局, 這已經可以使用在項目的正常發佈中,  但大多數人喜歡採用Fragment的方式進行實現。
筆者在此處建議, 希望兩種方式都能掌握並靈活應用。
ps: 因爲Fragment較爲重要,所以本篇博客會進行基本的Fragment講解

Fragment與Tab佈局,面世的觀念都是一樣的,都是希望在窄小的屏幕上進行多功能的操作,提高用戶的體驗性。而Fragment的面世則將其Tab的實現給具體了。
Fragment的用法與Activity類似,事實上你可以將Fragment簡單的理解爲就是Activity,因爲Fragment也具備者與Activity相同的生命週期,只不過Fragment的生命週期是建立在Activity的生命週期之上。 

關於Fragment與Activity的生命週期關聯的角度看,其實可以非常理解Android爲什麼要這麼做,Activity做爲UI的老大, 任何關於UI方面都應該要遵循Activity的生命週期。


下圖介紹Activity與Fragment的生命週期關聯:


這關係圖充分體現了Fragment與Activity的生命關聯形式, 想要操作Fragment的生命週期方法的前提是Activity的狀態爲create。

大致瞭解之後, 以下開始講解如何使用Fragment進行Tab佈局(在Fragment中, 分爲靜態使用和動態使用,。
ps: 筆者這裏只進行動態Fragment的Tab佈局實現, 若是採用靜態的方法實現Tab佈局,那麼我還是建議你使用ViewPager...


下圖爲最終效果圖:




(可以看出,使用Fragment與ViewPager的實現效果一樣,需注意佈局效果可自定義, 此處只講解實現的邏輯步驟



邏輯步驟:

1、創建兩個Fragment,分別代表btn1和btn2單擊後的佈局。
2、創建兩個Fragment對應的佈局文件(這兩步驟就當做Activity使用即可)
3、主佈局文件中,使用FragmentLayout組件進行頁面的佔位
4、主Activity中,監聽其按鈕單擊,分別調用Fragment在FragmentLayout中顯示即可



1)下圖爲整個項目工程結構




2)定義Fragment類

public class FragmentOne extends Fragment {

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

		return inflater.inflate(R.layout.fragment_one, container, false);
	}

}
返回的View類型代表將會在界面中顯示的視圖文件,這裏引用到了fragment_one.xml  , 現在進行定製該文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical" >
	
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:text="fragment one"
        android:textSize="20pt" />

</LinearLayout>

至此,第一個Fragment已經定義完成,  第二個Fragment與第一個定義的代碼一樣,就不貼出代碼,看效果圖即可;

3)定義主界面佈局文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <FrameLayout
        android:id="@+id/id_fragment"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

    <LinearLayout
        android:id="@+id/id_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >

        <Button
            android:id="@+id/id_btn1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="btnStartClick"
            android:text="btn1" />

        <Button
            android:id="@+id/id_btn2"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="btnStartClick"
            android:text="btn2" />
    </LinearLayout>

</LinearLayout>

此處佈局文件中具有一個FragmentLayout組件,你可以理解爲FragmentLayout就是一個Fragment顯示的佔位組件。

4)MainActivity.java類

4.1)自定義屬性
private FragmentManager fm;
private FragmentTransaction ft;
private List<Fragment> fragments;

FragmentManager 對Fragment操作的整體管理類,主要用於創建FragmentTransaction對象。
FragmentTransaction對Fragment操作的類, 還記得在MainActivity的xml文件中定義的FragmentLayout組件嗎。 此類對象可對他進行操作。

   以下介紹FragmentTransaction操作的核心方法:

add(): 向Activity中添加一個Fragment

remove()
從Activity中移除一個Fragment,如果被移除的Fragment沒有添加到回退棧(回退棧後面會詳細說),這個Fragment實例將會被銷燬。
replace()
使用另一個Fragment替換當前的,實際上就是remove()然後add()的合體~
hide()
隱藏當前的Fragment,僅僅是設爲不可見,並不會銷燬
show()

顯示之前隱藏的Fragment
detach()
會將view從UI中移除,和remove()不同,此時fragment的狀態依然由FragmentManager維護。
attach()
重建view視圖,附加到UI上並顯示。
commit()//提交一個事務


4.2)初始化基本信息
<span style="white-space:pre">	</span>/**
	 * 初始化
	 */
	private void init() {

		if (fragments == null) {
			fragments = new ArrayList<Fragment>();
		}

		fragments.add(new FragmentOne());
		fragments.add(new FragmentTwo());


// 以上步驟都爲初始化一個List<Fragment> 數據
		fm = getFragmentManager();    // 在Activity中可直接獲取到Fragment的管理類
		ft = fm.beginTransaction();   // 注意:任何FragmentLayout操作Fragment的類都需要在一個事務中進行(相信如果有數據庫基礎的同學應該很好理解。

		ft.replace(R.id.id_fragment, fragments.get(0)); // 替換方法,代表將FragmentLayout組件使用一個Fragment類進行替換掉(注意第一個參數就是FagmentLayout


ft.commit();// 一定需要提交此事務}

  監聽按鈕單擊事件

<span style="white-space:pre">	</span>public void btnStartClick(View v) {
		switch (v.getId()) {
		case R.id.id_btn1:
			ft = fm.beginTransaction();
			ft.replace(R.id.id_fragment, fragments.get(0));
			ft.commit();
			break;

		case R.id.id_btn2:
			ft = fm.beginTransaction();
			ft.replace(R.id.id_fragment, fragments.get(1));
			ft.commit();
			break;
		}
	}

現在,所有的代碼已經顯示完畢。 這可能比使用ViewPager實現具有一定的難度(考慮到了原子性),但Fragment是必不可少的一個組件知識點,學習者們務必掌握!

ps: 小細節,如果該FragmentLayout組件你是採用add方式進去,則若是想要顯示第二張Fragment的時候,需要先調用hide()方法將其隱藏掉,否則會出現疊加的效果!








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