Fragment是Android 3.0引入的心API,Fragment代表了Activity的子模块,因此可以吧Fragment理解为Activity片段(Fragment本身就是片段的意思)。Fragment拥有自己的生命周期,也可以接受它自己的输入事件。
Fragment必须被“嵌入”Activity中使用,虽然Fragment也拥有自己的生命周期,但Fragment的生命周期会受它所在的Activity的生命周期控制。例如,当Activity暂停时,该Activity内的所有Fragment都会暂停;当Activity被销毁时,该Activity内的所有Fragment都会被销毁。只有当该Activity处于活动状态时,程序员才可通过方法独立地操作Fragment。
关于Fragment,可以归纳出如下几个特征。
Android 3.0引入Fragment的初衷是为了适应大屏幕的平板电脑,这样可以容纳更多的UI组件,且UI组件之间存在交互关系。Fragment简化了大屏幕UI组件的设计,它不需要开发者管理组件包含关系的复杂变化,开发者适应Fragment对UI组件进行分组、模块化管理,就可以更方便低在运行过程中动态更新Activity的用户界面。
与创建Activity类似,开发者实现Fragment必须继承Fragment基类。
开发者实现Fragment,可以根据需要继承Fragment基类或者它的任意子类。接下来,实现Fragment与实现Activity非常相似,它们都需要实现与Activity类似的回调方法,例如onCreate()、onCreateView()、onStart()、onResume()、onPause()、onStop()等。
提示:开发Fragment与开发Activity非常相似,区别只是Activity需要继承Activity或其子类;而开发Fragment需要继承Fragment及其子类。与此同时,只要将原来写在Activity回调方法中的代码“移到”Fragment的回调方法即可。
通常来说,创建Fragment需要实现如下三个方法。
对于大部分Fragment而言,通常都会重写上面这三个方法。实际上开发者可以根据需要重写Fragment的任意回调方法,后面详细介绍Fragment的生命周期及其回调方法。
例如:
//重写改方法,改方法返回View将作为Fragment显示的最急哦按
@Override
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState)
{
//加载/res/layout/目录下的fragment_book_detail.xml布局文件
View rootview = inflater.inflate(R.layout.fragment_book_list,container,false);
if(book != null){
//让book_title文本框显示book对象的title属性
(TextView)rootView.findViewById(R.id.book_title)).setText(book.title);
//让book_desc文本框显示book对象的desc属性
((TextView)rootView.findViewById(R.id.book_desc)).setText(book.desc);
}
return rootView;
}
为了在Activity中显示Fragment,还必须将Fragment添加到Activity中。奖Fragment添加到Activity中有如下两种方式。
Activity的getFragmentManager()方法可返回FragmentManager,FragmentManager对象的beginTransaction()方法即可开启并返回FragmentTransaction对象。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:name="com.test.example.bookfragment"
android:id="@+id/book_list"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"/>
<FrameLayout
android:id="@+id/book_detail_container"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3"/>
LinearLayout>
上面布局文字使用fragment../>元素添加了BookListFragment,改Activity的左边将会显示一个ListFragment,右边只是一个FrameLayout容器,该FrameLayout容器将会动态更新其中显示的Fragment。下面是Activity代码。
public class MaiActivity extends Activity implements BookListFragment.Callbacks{
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
//加载res/layout目录下的activity_book_twopane.xml布局文件
setContentView(R.layout.activity_book_twopane);
}
//实现Callbacks接口必须实现的方法
@Override
public void onItemSelected(Integer id){
//创建Bundle准备向Fragment传入参数
Bundle arguments = new Bundle();
arguments.putInt(BookDetailFragment.ITEM_ID,id);
//创建BookDetialFragment对象
BookDetailFragment fragment = new BookDetailFragment();
//向Fragment传入参数
fragment.setArguments(arguments);
//使用fragment替换book_detail_container容器当前显示的Fragment
getFragmentManager.benginTransaction().replace(R.id.detail.container,fragment).commit();//①
}
}
上面程序中①号粗体字代码就调用了FragmentTransaction的replace()方法动态更新ID为book_detail_container容器(也就是前面布局文件中的FrameLayout容器)中显示的Fragment。
将Fragment添加到Activity之后,Fragment必须与Activity交互信息,这就需要Fragment能获取它所在的Activity,Activity也能获取它所包含的任意Fragment。可按如下方式进行。
提示:
在界面布局文件中使用 fragment…/>元素添加到Fragment时,可以为 Fragment …>元素指定android:id或者android:tag属性。这两个属性都可以标识该Fragment,接下来Activity通过findFragmentById(int id)或findFragmentByTag(String tag)来获取该Fragment。
除此之外,Fragment与Activity需要相互传递数据,可按如下方式进行。