Android - 用Fragments實現動態UI - 建立靈活的UI

當設計程序來支持各類不同的屏幕尺寸時,能夠在不一樣的佈局中重用fragment來根據可用的屏幕大小來優化用戶體驗。html

例如,在手機上可能使用一個fragment來使用單窗口用戶體驗比較合適。可是,你可能想在平板上邊靠邊的設置兩個fragment由於有更寬的屏幕向用戶展現更多信息。java

 

 圖1.兩個fragment,同一個activity在不一樣的屏幕大小上的不一樣展示形式。在大屏幕上,兩個fragment邊靠邊,可是在手機設備上,一次只顯示一個fragment所以fragment在用戶切換的時候替換另外一個。android

爲了建立動態的體驗, FragmentManager類提供了方法能夠在運行時添加,刪除,替換activity中的fragment。app

在運行時向activity添加fragmentide

不單單能夠在activity佈局文件中定義fragment(前面介紹了使用<fragment>元素),也能夠在activity運行時加入fragment。若是計劃在activity運行時改變fragment,這個頗有必要。佈局

要處理添加刪除fragment,可使用FragmentManager來建立一個FragmentTransation,它提供了API來添加,替換和fragment的其餘事務。優化

若是activity容許fragment刪除或者替換,應該在activity的onCreate()方法中添加fragment的初始化信息。spa

處理fragment有一個重要的規則,特別是在運行時添加的fragment:fragment在佈局中必須有一個View容器。設計

下面的佈局是上一篇中佈局的一個變形,這裏一次只顯示一個fragment。爲了用一個fragment替換另外一個,這個activity的佈局包含一個空的FrameLayout做爲fragment的容器。code

這個文件名和前面一篇中佈局的文件名是同樣的,可是佈局文件夾沒有large標識,因此這個佈局使用在小屏幕上由於小屏幕不須要同時顯示兩個fragment。

res/layout/news_articles.xml:

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

在activity中,使用Support Library中的API getSupportFragmentManager()來得到FragmentManager.而後調用beginTransaction()來建立一個FragmentTransaction再調用add()添加一個fragment。

可使用一個FragmentTransaction來處理多個activity的fragment rransaction。當準備好執行這些改變後,調用commit()。

例如,這裏展現瞭如何把fragment加到前一個佈局上:

 1 import android.os.Bundle;
 2 import android.support.v4.app.FragmentActivity;
 3                                                       
 4 public class MainActivity extends FragmentActivity {
 5     @Override
 6     public void onCreate(Bundle savedInstanceState) {
 7         super.onCreate(savedInstanceState);
 8         setContentView(R.layout.news_articles);
 9                                                      
10                                             
11         //檢查activity的佈局是使用fragment_container FrameLayout的版本
12         if (findViewById(R.id.fragment_container) != null) {
13                                                       
14             // 可是,若是是從前一個狀態恢復的話
15             // 咱們不須要作任何事情,直接返回就好了,不然就會重疊fragments。
16             if (savedInstanceState != null) {
17                 return;
18             }
19                                                       
20             //建立一個Fragment實例
21             HeadlinesFragment firstFragment = new HeadlinesFragment();
22                                                                   
23             //有可能activity是從Intent中的特殊指令建立的,
24             //把Intent的extras當參數傳遞給fragment
25             firstFragment.setArguments(getIntent().getExtras());
26                                                                   
27             // 把fragment加入到'fragment_container' FrameLayout
28             getSupportFragmentManager().beginTransaction()
29                     .add(R.id.fragment_container, firstFragment).commit();
30         }
31     }
32 }


由於fragment是在運行時加入到FrameLayout的(不是在activity的佈局文件中用<fragment>定義的),activity就能夠移出這個fragment而後用一個不一樣的替換它。

用一個fragment替換另外一個

換掉一個fragment的方法和添加一個類似,可是須要使用replace()方法,而不是add()

記住當執行fragment切換時,例如添加或者刪除,常常要容許用戶切換回去來恢復這些改變。爲了容許用戶在fragment切換時切換回去,應該在提交FragmentTransaction以前調用addToBackStack()。

注意:當移除或者替換一個fragment而後加到切換的返回堆棧中時,被移除的fragment是Stopped狀態(並非Destroyed)。若是用戶切換回去來恢復fragment,它就重啓。若是沒有把它加到返回堆棧中,fragment被移除或者替換時就銷燬了。

用一個fragment替換另外一個的例子:

 1 //建立一個fragment,而後把應該展現的文章的參數傳給它
 2 ArticleFragment newFragment = new ArticleFragment();
 3 Bundle args = new Bundle();
 4 args.putInt(ArticleFragment.ARG_POSITION, position);
 5 newFragment.setArguments(args);
 6                                     
 7 FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
 8                                     
 9 //用這個fragment替換掉fragment_container view 中的東西,
10 //而後把transaction加到返回堆棧中,這樣用戶就能夠切換回去了
11 transaction.replace(R.id.fragment_container, newFragment);
12 transaction.addToBackStack(null);
13                                     
14 //提交transaction
15 transaction.commit();

addToBackStack()方法帶一個可選的字符串參數,用來指定一個惟一的transaction名字。這個名字並非必需的除非須要用FragmentManager.BackStackEntryAPI的一些特使操做。

 

 

上一篇:Android - 用Fragments實現動態UI - 建立Fragment

下一篇:Android - 用Fragments實現動態UI - 和其餘Fragments通訊

相關文章
相關標籤/搜索