1. 程式人生 > >Android Studio 單刷《第一行程式碼》系列 05 —— Fragment 基礎

Android Studio 單刷《第一行程式碼》系列 05 —— Fragment 基礎

前情提要(Previously)

本系列將使用 Android Studio 將《第一行程式碼》(書中講解案例使用Eclipse)刷一遍,旨在為想入坑 Android 開發,並選擇 Android Studio 作為開發 IDE 的同學開路。
PS:其實我就是現學現賣,希望我能堅持刷完。

在前面已經學習了 Android 四大元件中的 Activity,這次來學習一下Activity 中的 Fragment。

系列目錄在此:

摘要(Abstract)

Fragment 的簡介、簡單使用、動態載入。

Fragment 是什麼

先來看看 API Guides 裡是怎麼說的。

  • A Fragment represents a behavior or a portion of user interface in an Activity. You can combine multiple fragments in a single activity to build a multi-pane UI and reuse a fragment in multiple activities. You can think of a fragment as a modular section of an activity, which has its own lifecycle, receives its own input events, and which you can add or remove while the activity is running (sort of like a "sub activity" that you can reuse in different activities).
    A fragment must always be embedded in an activity and the fragment's lifecycle is directly affected by the host activity's lifecycle.
  •  
  • Fragment 必須嵌入在 Activity 中使用。
  • Fragment 的生命週期 是受 Activity 影響的。
  • 可以在一個 Activity 中使用多個 Fragment。
  • Fragment 可以在多個 Activity 中重用。

說了這麼多,也沒說 Fragment 到底是什麼,只好繼續往下看。

Design Philosophy(設計理念)

Android introduced fragments in Android 3.0 (API level 11), primarily to support more dynamic and flexible UI designs on large screens, such as tablets. Because a tablet's screen is much larger than that of a handset, there's more room to combine and interchange UI components. Fragments allow such designs without the need for you to manage complex changes to the view hierarchy. By dividing the layout of an activity into fragments, you become able to modify the activity's appearance at runtime and preserve those changes in a back stack that's managed by the activity.

  • Android3.0 裡出現的。
  • 為了更加合理和充分地利用大螢幕的空間。

其實就是為了更好的同時支援手機和平板(我是這麼認為的)。看下面這個來自 Android API Guides 中的圖就明白了。

fragments

Fragment 簡單使用

練習開始,新建一個 FragmentTest 的專案,在一個 Activity 中新增兩個 Fragment,並列顯示。

  • 新建一個左側佈局 left_fragment.xml,放一個 Button 在裡面,程式碼如下:

 

  <Button
      android:id="@+id/button"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_gravity="center_horizontal"
      android:text="Button" />

 

  • 同樣的新建一個右側佈局 right_fragment.xml,放一個 TextView 在裡面,程式碼省略。

  • 新建 LeftFragment 類,繼承自 Fragment,重寫 onCreateView() 方法,在這個方法中通過 LayoutInflater 將佈局動態載入進來,程式碼如下:

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

  • 同樣新建 RightFragment 類,程式碼省略。

  • 修改 activity_main.xml,刪掉預設的 TextView 新增 Fragment,程式碼如下:

<fragment
    android:id="@+id/left_fragment"
    android:name="com.addict.fragmenttest.LeftFragment"
    android:layout_width="0dp"
    android:layout_height="match_parent"
    android:layout_weight="1"></fragment>

<fragment
    android:id="@+id/right_fragment"
    android:name="com.addict.fragmenttest.RightFragment"
    android:layout_width="0dp"
    android:layout_height="match_parent"
    android:layout_weight="1"></fragment>

這樣最簡單的 Fragment 示例就寫好了,執行一下程式看看吧。

動態新增 Fragment

  • 新建一個 another_right_fragment.xml,放一個 TextView 在裡面,設定佈局的顏色、TextView 的內容,程式碼如下:

 

  <TextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_gravity="center_horizontal"
      android:text="this is another right fragment."
      android:textSize="20sp" />

 

  • 同樣新建一個 AnotherRightFragment 類,程式碼省略。

  • 修改 activity_main.xml 的程式碼,將右側的 Fragment 放在 FrameLayout 中,程式碼如下:

<fragment
    android:id="@+id/left_fragment"
    android:name="com.addict.fragmenttest.LeftFragment"
    android:layout_width="0dp"
    android:layout_height="match_parent"
    android:layout_weight="1"></fragment>

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

    <fragment
        android:id="@+id/right_fragment"
        android:name="com.addict.fragmenttest.RightFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"></fragment>
</FrameLayout>
  • 修改 MainActivity 中的程式碼,在點選 Button 是動態新增 Fragment,程式碼如下:
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Button button = (Button) findViewById(R.id.button);
    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            AnotherRightFragment fragment = new AnotherRightFragment();
            FragmentManager fragmentManager = getFragmentManager();
            FragmentTransaction transaction = fragmentManager.beginTransaction();
            transaction.replace(R.id.right_layout, fragment);
            transaction.commit();
        }
    });
}

這樣就完成了,執行一下看看吧。小結一下動態新增 Fragment:

  1. 建立待新增的 Fragment 的例項。
  2. 獲取 FragmentManager,通過 getFragmentManager() 方法。
  3. 開啟事務。
  4. 向容器內加入 Fragment,使用 replace() 方法,引數為需要傳入的容器 id、待新增的 Fragment 例項。
  5. 提交事務。

利用返回棧管理 Fragment

執行之前的程式,點選 Button 動態新增 Fragment 後,按下 Back 鍵我們發現程式直接退出了。那麼能不能做到按 Back 鍵回到上一個 Fragment 呢?

超簡單,在這句程式碼 transaction.commit(); 前再加一句程式碼 transaction.addToBackStack(null); 就可以了,試試看吧。

2015-03-21 更正

按照上面寫的加上這句程式碼 transaction.addToBackStack(null); 之後,我發現按下 Back 仍然沒有返回上一個 Fragment,還是直接退出程式了。Google Baidu 查了好久也沒弄明白原因。

寫了個解決辦法,在 MainActivity 中重寫了 onPressed() 方法,程式碼如下:

@Override
// 按下 Back 按鈕時觸發
public void onBackPressed(){
    FragmentManager fragmentManager = getFragmentManager();
    // 判斷 BackStack 中是否有 FragmentTransaction
    if(fragmentManager.getBackStackEntryCount() > 0){
        // FragmentTransaction 出棧,恢復前一個 Fragment
        fragmentManager.popBackStack();
        return;
    }
    super.onBackPressed();
}

其它(Miscellaneous)

儘管我試圖在本文中儘量完整的進行描述,但受限於篇幅和我的個人水平,本文難免有所遺漏,歡迎在評論中指出。
如果您覺得閱讀本文對您有幫助,請點一下“推薦”按鈕,您的“推薦”將是我最大的寫作動力!

關於作者(About Me)

addict
原文連結:http://www.cnblogs.com/DebugLife/p/4355669.html