原文地址:http://developer.android.com/training/basics/fragments/fragment-ui.html
当设计你的程序去支持大部分屏幕尺寸时,你可以在不同的布局文件中复用你的碎片,在不同的屏幕空间中优化你的用户体验。
例如,手机中可能一次只适合显示一个碎片,相反的,在大屏幕设备中,你可能想在一个界面中挨着显示很多个碎片。
<ignore_js_op>
图解:一个activity在不同屏幕尺寸的显示效果。在大屏幕中,两个碎片紧挨着显示,在手机中,一次只显示一个碎片。
FragmentManager类提供一些函数,让你可以在程序运行时添加,删除和替换碎片,从而产生动态显示效果。
运行中添加一个碎片
上一个教程中,我们在XML文件中添加碎片,不同的是,你现在可以在activity运行期间添加一个碎片,在activity生命周期中改变碎片是非常有必要的。
要实现碎片的添加和删除,你需要使用FragmentManager去创建一个FragmentTransaction,它提供API去添加,删除,替换和执行其他碎片转换。
如果你想允许碎片被移除和替换,你需要在activity的onCreate()函数中初始化碎片。
一个重要的规定是:要操作碎片,尤其是运行中添加碎片,碎片必须有一个view容器,这个容器包含了碎片的布局。
下面这个布局和上一个课程的有所不同,它一次只显示一个碎片。为了能用其他碎片替换这一个碎片,activity布局需要包含一个空的FrameLayout碎片容器。
需要提醒的是,下面的文件名和上一课的一样,但是目录没有large限定符,所以,这个布局是当设备屏幕尺寸小于large的时候才会被应用,因为屏幕太小,不够同时显示多个碎片。
res/layout/news_articles.xml:
<FrameLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/fragment_container"android:layout_width="match_parent"android:layout_height="match_parent"/>
在你的activity中,调用getSupportFragmentManager()去取得一个FragmentManager。然后调用beginTransaction()去创建一个FragmentTransaction,再调用add()去添加一个碎片。
你可以使用FragmentTransaction去处理多个碎片,当你确认好要改变碎片时,你必须调用commit()。
例如,下面演示了怎么添加一个碎片:
import android.os.Bundle;import android.support.v4.app.FragmentActivity;publicclassMainActivityextendsFragmentActivity{@Overridepublicvoid onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState); setContentView(R.layout.news_articles);// 检查activity使用的布局中是否有碎片容器if(findViewById(R.id.fragment_container)!=null){// 如果我们只是恢复先前的状态, // 那么我们什么都不用做,只是返回或者我们可以覆盖先前的碎片if(savedInstanceState !=null){return;}// 创建一个碎片实例HeadlinesFragment firstFragment =newHeadlinesFragment();// 使用特别的指令从一个Intent开始一个activity, // 把Intent中附加的数据做为碎片的参数。 firstFragment.setArguments(getIntent().getExtras());// 添加碎片到碎片容器中 getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, firstFragment).commit();}}}
因为随便是在运行中被添加到FrameLayout容器中的,所以activity可以用一个不同的碎片替换它,或者是删除它。
用另外一个碎片替换当前碎片
替换一个碎片的步骤和添加一样简单,只需要把add改为replace就可以了。
记住,当你进行碎片操作时,比如替换或者删除,你需要让用户可以返回和撤销改变。为了实现这些,你需要在提交碎片操作前调用addToBackStack()。
提示:当你删除或者替换一个碎片,并且添加了这些操作在后退堆栈,碎片移除会被停止(没有被销毁),如果用户想返回恢复碎片,它就会被重新开启。如果没有加入后退堆栈,这个碎片就会在替换或者删除的时候被销毁。
替换的例子:
// 创建一个碎片,传递一个参数给它,指定显示的内容ArticleFragment newFragment =newArticleFragment();Bundle args =newBundle(); args.putInt(ArticleFragment.ARG_POSITION, position); newFragment.setArguments(args);FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();// 替换碎片容器中的碎片, // 添加操作到后退堆栈中,以便用户可以返回 transaction.replace(R.id.fragment_container, newFragment); transaction.addToBackStack(null);// 提交操作 transaction.commit();
addToBackStack()函数需要传递一个字符串参数,为操作指定一个独一无二的名称,这个名称不是必须的,除非你计划开始使用FragmentManager.BackStackEntryAPI执行高级的碎片操作。