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通讯

相关文章
相关标签/搜索