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


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

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

 

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

為了創建動態的體驗, FragmentManager類提供了方法可以在運行時添加,刪除,替換activity中的fragment。

在運行時向activity添加fragment

不僅僅可以在activity布局文件中定義fragment(前面介紹了使用<fragment>元素),也可以在activity運行時加入fragment。如果計划在activity運行時改變fragment,這個很有必要。

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

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

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

下面的布局是上一篇中布局的一個變形,這里一次只顯示一個fragment。為了用一個fragment替換另一個,這個activity的布局包含一個空的FrameLayout作為fragment的容器。

這個文件名和前面一篇中布局的文件名是一樣的,但是布局文件夾沒有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通信

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM