構建靈活的界面

在設計支持各類屏幕尺寸的應用時,你能夠在不一樣的佈局配置中重複使用 Fragment ,以便根據相應的屏幕空間提供更出色的用戶體驗。html

例如,一次只顯示一個 Fragment 可能就很適合手機這種單窗格界面,但在平板電腦上,你可能須要設置並列的 Fragment,由於平板電腦的屏幕尺寸較寬闊,可向用戶顯示更多信息。java

   

圖 1: 兩個 Fragment,顯示在不一樣尺寸屏幕上同一 Activity 的不一樣配置中。在較寬闊的屏幕上,兩個 Fragment 可並列顯示;在手機上,一次只能顯示一個 Fragment,所以必須在用戶導航時更換 Fragment。android

利用 FragmentManager 類提供的方法,你能夠在運行時添加、移除和替換 Activity 中的 Fragment,以便爲用戶提供一種動態體驗。app

在運行時向 Activity 添加 Fragment


你能夠在 Activity 運行時向其添加 Fragment,而不用像上一課中介紹的那樣,使用 <fragment> 元素在佈局文件中爲 Activity 定義 Fragment。若是你打算在 Activity 運行週期內更改 Fragment,就必須這樣作。ide

要執行添加或移除 Fragment 等事務,你必須使用 FragmentManager 建立一個 FragmentTransaction,後者可提供用於執行添加、移除、替換以及其餘 Fragment 事務的 API。佈局

若是 Activity 中的 Fragment 能夠移除和替換,你應在調用 Activity 的 onCreate() 方法期間爲 Activity 添加初始 Fragment(s)。spa

在處理 Fragment(特別是在運行時添加的 Fragment )時,請謹記如下重要規則:必須在佈局中爲 Fragment 提供 View 容器,以便保存 Fragment 的佈局。設計

下面是上一課所示佈局的替代佈局,這種佈局一次只會顯示一個 Fragment。要用一個 Fragment 替換另外一個 Fragment, Activity 的佈局中須要包含一個做爲 Fragment 容器的空 FrameLayoutcode

請注意,該文件名與上一課中佈局文件的名稱相同,但佈局目錄沒有 large 這一限定符。所以,此佈局會在設備屏幕小於「large」的狀況下使用,緣由是尺寸較小的屏幕不適合同時顯示兩個 Fragment。xml

res/layout/news_articles.xml:

    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
       
android:id="@+id/fragment_container"
       
android:layout_width="match_parent"
       
android:layout_height="match_parent" />
   

   

在 Activity 內部,使用 Support Library API 調用 getSupportFragmentManager() 以獲取 FragmentManager,而後調用 beginTransaction() 建立 FragmentTransaction,同時調用 add() 添加 Fragment。

你可使用同一個 FragmentTransaction 對 Activity 執行多 Fragment 事務。當你準備好進行更改時,必須調用 commit()

例如,下面介紹瞭如何爲上述佈局添加 Fragment :

    import android.os.Bundle;
   
import android.support.v4.app.FragmentActivity;

   
public class MainActivity extends FragmentActivity {
       
&Override
       
public void onCreate(Bundle savedInstanceState) {
           
super.onCreate(savedInstanceState);
            setContentView
(R.layout.news_articles);

           
// 確認 Activity 使用的佈局版本包含
           
// fragment_container FrameLayout
           
if (findViewById(R.id.fragment_container) != null) {

               
// 不過,若是咱們要從先前的狀態還原,
               
// 則無需執行任何操做而應返回
               
// 不然就會獲得重疊的 Fragment 。
               
if (savedInstanceState != null) {
                   
return;
               
}

               
// 建立一個要放入 Activity 佈局中的新 Fragment
               
HeadlinesFragment firstFragment = new HeadlinesFragment();

               
// 若是此 Activity 是經過 Intent 發出的特殊指令來啓動的,
               
// 請將該 Intent 的 extras 以參數形式傳遞給該 Fragment
                firstFragment
.setArguments(getIntent().getExtras());

               
// 將該 Fragment 添加到「fragment_container」FrameLayout 中
                getSupportFragmentManager
().beginTransaction()
                       
.add(R.id.fragment_container, firstFragment).commit();
           
}
       
}
   
}
   

   

因爲該 Fragment 已在運行時添加到 FrameLayout 容器中,而不是在 Activity 佈局中經過 <fragment> 元素進行定義,所以該 Activity 能夠移除和替換這個 Fragment 。

用一個 Fragment 替換另外一個 Fragment


替換 Fragment 的步驟與添加 Fragment 的步驟類似,但須要調用 replace() 方法,而非 add()

請注意,當你執行替換或移除 Fragment 等 Fragment 事務時,最好能讓用戶向後導航和「撤消」所作更改。要經過 Fragment 事務容許用戶向後導航,你必須調用 addToBackStack(),而後再執行 FragmentTransaction

注意:當你移除或替換 Fragment 並向返回堆棧添加事務時,已移除的 Fragment 會中止(而不是銷燬)。若是用戶向後導航,還原該 Fragment,它會從新啓動。若是你沒有向返回堆棧添加事務,那麼該 Fragment 在移除或替換時就會被銷燬。

替換 Fragment 的示例:

    // 建立 Fragment 併爲其添加一個參數,用來指定應顯示的文章
   
ArticleFragment newFragment = new ArticleFragment();
   
Bundle args = new Bundle();
    args
.putInt(ArticleFragment.ARG_POSITION, position);
    newFragment
.setArguments(args);

   
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

   
// 將 fragment_container 中的內容替換爲此 Fragment ,
   
// 而後將該事務添加到返回堆棧,以便用戶能夠向後導航
    transaction
.replace(R.id.fragment_container, newFragment);
    transaction
.addToBackStack(null);

   
// 執行事務
    transaction
.commit();
   
View

   

addToBackStack()  方法可接受可選的字符串參數,來爲事務指定獨一無二的名稱。除非你打算使用 FragmentManager.BackStackEntry API 執行高級 Fragment 操做,不然無需使用此名稱。

相關文章
相關標籤/搜索