介绍

fragment是android 3.0(API 11) 中引入的。可以将fragment看成是activity中的一个模块,也有自己的生命周期,能够处理用户事件。

通过fragment可以方便的实现在多个activity中实现相同的布局。在做android平板开发时,可以和手机程序共用同一段代码。

如果需要在界面中动态添加、替换、删除某一块模块,也可以通过fragment实现。

基本使用方式

静态使用

首先创建一个简单的布局文件fragment_simple.xml,当做fragment的布局,里面代码如下

1
2
3
4
5
6
7
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="这是一个简单的fragment"/>
</LinearLayout>

然后新建文件SimpleFragment, 继承自Fragment,重写onCreateView方法

1
2
3
4
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_simple, container, false);
}

最后在需要使用的activity中加入,通过name属性指定具体使用哪一个fragment

1
2
3
4
5
<fragment
android:id="@+id/fragment_static"
android:name="com.example.seewhy.androidfragmentdemo.SimpleFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

动态使用

通过fragment可以使程序在运行过程中替换某一块界面,比如我想在点击一个button之后显示一块内容。
先要在布局文件中创建一个容器,定义id为container。

1
2
3
4
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

然后在button的onClick中写如下面这段代码,实现将container替换为自己需要的fragment。
其中transaction就是事务的意思,在manager.beginTransaction与transaction.commit();之间的代码,要么全部执行成功,如果某一步执行失败,那么之前执行的也都会被撤销,保证事务的原子性。

1
2
3
4
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.container, new SimpleFragment());
transaction.commit();

常用的FragmentTransaction操作有add、remove、hide、addToBackStack等等。

使用v4包还是app包

fragment同时存在于android.support.v4.app和android.app两个包中。其中v4包是为了使android 3.0之前的系统能够使用fragment而存在。选择的时候,如果能够确保使用环境在android 3.0以上,那么应该使用app包中的fragment。Android官方文档中的Fragment的例子也是以app包中的Fragment来讲解的。如果需要兼容低版本android,那么就使用v4,v4包最低能兼容到android 1.6。
但是,项目中不能同时存在v4和app两个包中的fragment,只能选择其中一个使用。
以下是在v4包中使用fragment的注意事项

  1. 如果使用了v4包的fragment,那么所在的Activity一定要继承FragmentActivity。
  2. FragmentManager()需要换成getSupportFragmentManager()

生命周期

这个是从官网找来的fragment生命周期图,可以看到Fragment比Activity多了几个额外的生命周期回调方法:

  • onAttach(Activity)-
    当Fragment与Activity发生关联时调用。

  • onCreateView(LayoutInflater, ViewGroup,Bundle)
    创建该Fragment的视图

  • onActivityCreated(Bundle)
    当Activity的onCreate方法返回时调用

  • onDestoryView()
    与onCreateView想对应,当该Fragment的视图被移除时调

  • onDetach()
    与onAttach相对应,当Fragment与Activity关联被取消时调用
    注意:除了onCreateView,其他的所有方法如果你重写了,必须调用父类对于该方法的实现,

其他

以上介绍了fragment基本的使用方式。
官方还提供了ListFragment用于显示在listview,
FragmentPagerAdapter用于fragment与pagerAdapter结合使用。
如果需要在pageAdapter切换时保留fragment的数据,可以使用FragmentStatePagerAdapter。

FragmentPagerAdapter:对于不再需要的fragment,选择调用detach方法,仅销毁视图,并不会销毁fragment实例。

FragmentStatePagerAdapter:会销毁不再需要的fragment,当当前事务提交以后,会彻底的将fragmeng从当前Activity的FragmentManager中移除,state标明,销毁时,会将其onSaveInstanceState(Bundle outState)中的bundle信息保存下来,当用户切换回来,可以通过该bundle恢复生成新的fragment,也就是说,你可以在onSaveInstanceState(Bundle outState)方法中保存一些数据,在onCreate中进行恢复创建。

如上所说,使用FragmentStatePagerAdapter当然更省内存,但是销毁新建也是需要时间的。一般情况下,如果你是制作主页面,就3、4个Tab,那么可以选择使用FragmentPagerAdapter,如果你是用于ViewPager展示数量特别多的条目时,那么建议使用FragmentStatePagerAdapter。

还有最新的sdk已经把TabActivity标记为deprecated,如果要实现tabbar的效果,应该使用FragmentTabHost。

DialogFragment在android 3.0时被引入。是一种特殊的Fragment,用于在Activity的内容之上展示一个模态的对话框。典型的用于:展示警告框,输入框,确认框等等。具体可以看这里

参考资料