android文档之Fragment


一个Fragment代表Activity用户界面的一个行为或一部分。可以绑定多个fragment到一个单独的activity来创建多面板的UI,也可以在多个activity中重复使用一个Fragment。可以把Fragment当做activity的拥有独立的生命周期可以接收输入时间的模块区域。可以在activity运行的状态下添加和移除Fragment。

 

一个Fragment必须被嵌入activity中,并且Fragment的生命周期被主activity的生命周期所影响。例如,如果一个activity被暂停,那么它拥有的所有的Fragment都被暂停。然而,当一个activity运行中(处于Resumed状态),可以独立地操作每个Fragment,例如添加和删除。当执行这样的Fragment事务时,可以将它添加到activity管理着的返回栈中。Activity中的返回栈是Fragment事务记录。返回栈允许通过BACK按钮返回到之前的Fragment事务。

 

当添加一个Fragment作为activity布局的一部分时,它包含在一个ViewGroup的视图层中。可以在布局中使用<fragment>元素或者在代码中将它添加个一个已经存在的ViewGroup中。

 

设计思想

Android在3.0版引入Fragment(API对应版本为Honeycomb),主要用来支持在大屏幕上的更多动态的可伸缩的用户界面,例如平板。因为平板的屏幕比手机屏幕大的多,有更大的空间来管理复杂的UI组件。Fragment允许这样的设计而不需要管理视图层复杂的变化。通过将activity的视图分割到Fragment中可以在运行的过程中修改activity的外貌,并且将这些变化保存到返回栈中。

 

 

执行Fragment事务

使用Fragment最大的特点是你可以添加、删除、替代以及执行其他的响应用户界面行为。每一个你提交给Activity的变化的集合被称为一个事务,并且可以通过Fragment Transaction的api来执行。你也可以保持每个事务到一个Activity管理着的back栈中,运行用户向后返回操作(类似于Activity的back键行为)。

 

可以如下获得FragmentTransaction对象

FragmentManager fragmentManager= getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

 

每一个事务是你想要同时执行的变化的集合。可以通过add(),remove(),replace()方法来设置你想要在一个事务中执行的变化。为了应用事务到activity,必须调用commit()。

 

在调用commit()之前,可以调用addToBackStack()方法将事务添加到Fragment事务的返回栈(a back stack)中。这个栈被activity管理者,并且允许用户通过按BACK按钮返回到前一个Fragment状态。

 

下面是一个Fragment替换另一个Fragment,并且保持之前状态到返回栈中的例子:

 

// Create new fragment and transaction
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();

// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);

// Commit the transaction
transaction.commit();

 

如果你添加多个变化到事务(transaction)中,那么所有在调用commit()方法之前的变化,都会应用到一个同一个事务中。

 

将变化添加到FragmentTransaction中的顺序不重要但是:

 ·必须在最后调用commit()方法

 ·如果你添加多个Fragment到同一个View容器,那么你添加的顺序决定他们显示的View等级

 

如果不调用addToBackStack(),当执行执行移除Fragment操作时,但移除事务提交以后,Fragment将被销毁,并且用户不可以返回。相反的如果你调用了addToBackStack(),但你移除Fragment时,那个Fragment被停止掉了,当按BACK返回时将被Resume。

 

提示:对于每一个Fragment事务,你可以在commit()通过调用setTransition()应用一个过渡动画。

 

调用commit()方法,并不会立即执行事务。而是,降到放到activity的ui线程中去,知道线程去执行。如果必要,可以调用在UI线程中executePendingTransactions()来执行通过commit()方法提交的事务。通常不必这么做,除非那个事务依赖其他线程中的工作。

 

警告:你只可以在一个activity保持状态之前(当用户离开activity时)提交一个事务,否则会出现异常。因为提交过后的状态可能会丢失,如果activity被重新加载的时候。如果对于丢失也无关紧要的情况,可以调用commitAllowingStateLoss()。

 

与Activity的通信

 

尽管一个Fragment是独立于Activity被实现的,并且可以在多个activity中使用,但是一个已经实例化的Fragment对象是被绑定到包含它的activity中的。

 

特别的,Fragment可以通过getActivity()获得Activity的实例来访问,并且可以容易的执行一些任务,例如获得一个View:

View listView = getActivity().findViewById(R.id.list);

同样的,activity可以调用Fragment中的方法,通过FragmentManager来获得Fragment的引用,使用findFragmentById()或者findFragmentByTag()。例如:

ExampleFragment fragment = (ExampleFragment) getFragmentManager().findFragmentById(R.id.example_fragment);

 

创建到activity的事件回调

 

在一些情况下,你可能需要一个Fragment与activity分享事件。一个好的方法是在Fragment中定义一个回调接口,并且要activity来实现该接口。当一个activity从接口接受一个回调,它可以与其他的在那个布局中的Fragment分享信息,如果有必要的话。

 

例如,如果一个新的应用程序在一个activity中有两个Fragment—一个显示文章标题的列表(Fragment A)另一个显示文章内容(Fragment B)—那么Fragment A必须要告诉Activity当一个列表项被选择的时候,让后告诉Fragment B来显示文章。在这种情况下,OnArticleSelectedListener接口是在Fragment A中声明的:

 

public static class FragmentA extends ListFragment {
    ...
    // Container Activity must implement this interface
    public interface OnArticleSelectedListener {
        public void onArticleSelected(Uri articleUri);
    }
    ...
}

 

然后拥有那个Fragment的activity实现OnArticleSelectedListener接口,并且重写onArticleSelected()方法将来自FragmentA的事件通知Fragment B。为了保证主activity实现了接口,Fragment A在回调方法onAttach()(系统在将Fragment添加到activity中时调用)中通过强制转换onAttach()的参数来初始化一个OnArticleSelectedListener对象。

 

public static class FragmentA extends ListFragment {
    OnArticleSelectedListener mListener;
    ...
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mListener = (OnArticleSelectedListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement OnArticleSelectedListener");
        }
    }
    ...
}

 

如果那个activity没有实现接口,那么Fragment会抛出ClassCastException。如果成功了,表示mListener成员变量拥有一个实现了OnArticleSelectedListener接口的activity的引用。例如,如果FragmentA是ListFragment的子类,每一个用户点击一个列表项,系统将调用onListItemClick(),然后就会调用到onArticleSelected()方法来与activity分享事件:

 

public static class FragmentA extends ListFragment {
    OnArticleSelectedListener mListener;
    ...
    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        // Append the clicked item's row ID with the content provider Uri
        Uri noteUri = ContentUris.withAppendedId(ArticleColumns.CONTENT_URI, id);
        // Send the event and Uri to the host activity
        mListener.onArticleSelected(noteUri);
    }
    ...
}

 

The id parameterpassed to onListItemClick() is the row IDof the clicked item, which the activity (or other fragment) uses to fetch thearticle from the application's ContentProvider.

 

在行为栏(Action Bar)添加项目

 

Fragment可以通过onCreateOptionsMenu()发布菜单项到activity的选项菜单(包括行为栏)。为了让这个方法接受调用,你必须在onCreate()方法中调用setHasOptionsMenu()来表明Fragment想添加菜单项到选项菜单中(否则,Fragment将不调用onCreateOptionsMenu())。

 

任何从Fragment中要添加到选项菜单中的项目,都被追加到以及存在的菜单项。在一个菜单项被选中的时候,Fragment也接受onOptionsItemSelected()回调。

 

也可以在Fragment布局中通过调用registerForContextMenu()注册一个视图来提供上下文菜单。当用户打开上下文菜单时,Fragment接受一个到onCreateContextMenu()的调用。当用户选择上下文菜单的一项时,Fragment接受一个到onContextItemSelected()调用。

 

注解:尽管Fragment可以接受菜单项被点击的事件,但是activity是第一个接受回调的。如果Activity没有对被点击的菜单项事件处理,那么事件被传递到Fragment

 

处理Fragment的生命周期

 

管理Fragment的生命周期,有点像activity的生命周期。像activity一样,一个Fragment可以存在三种状态。

 http://www.xilele.com/shequ/showarticle.jhtml?id=943836
http://www.xilele.com/shequ/showarticle.jhtml?id=943835
http://www.xilele.com/shequ/showarticle.jhtml?id=943834
http://www.xilele.com/shequ/showarticle.jhtml?id=943833
http://www.xilele.com/shequ/showarticle.jhtml?id=943832
http://www.xilele.com/shequ/showarticle.jhtml?id=943831
http://www.xilele.com/shequ/showarticle.jhtml?id=943830
http://www.xilele.com/shequ/showarticle.jhtml?id=943829
http://www.xilele.com/shequ/showarticle.jhtml?id=943828
http://www.xilele.com/shequ/showarticle.jhtml?id=943827
http://www.xilele.com/shequ/showarticle.jhtml?id=943826
http://www.xilele.com/shequ/showarticle.jhtml?id=943825
http://www.xilele.com/shequ/showarticle.jhtml?id=943824
http://www.xilele.com/shequ/showarticle.jhtml?id=943823
http://www.xilele.com/shequ/showarticle.jhtml?id=943822
http://www.xilele.com/shequ/showarticle.jhtml?id=943821
http://www.xilele.com/shequ/showarticle.jhtml?id=943820
http://www.xilele.com/shequ/showarticle.jhtml?id=943819
http://www.xilele.com/shequ/showarticle.jhtml?id=943818
http://www.xilele.com/shequ/showarticle.jhtml?id=943817
http://www.xilele.com/shequ/showarticle.jhtml?id=943816
http://www.xilele.com/shequ/showarticle.jhtml?id=943815
http://www.xilele.com/shequ/showarticle.jhtml?id=943814
http://www.xilele.com/shequ/showarticle.jhtml?id=943813

Resume 状态

Fragment在运行的activity中是可见的

 

Paused状态

另一个activity在最前面并且拥有焦点,但是这个Fragment所在的activity仍然是可见的。(前景activity是透明或者没有占满整个屏幕)

 

Stopped状态

Fragment是不可见的。不管主activity被停止了或者Fragment被从当前activity中移除并添加到返回栈中。被停止的Fragment仍然是活着的()。所有的状态和成员信息都被系统保存着。然而,如果主activity被销毁,Fragment将不再被用户可见,并且会被销毁。

 

像activity一样,可以使用Bundle保存Fragment的状态,以防止activity所在的进程被销毁,当activity被重新创建的时候,需要恢复Fragment的状态。可以通过Fragment的onSaveInstanceState()回调保存状态,在onCreate(),onCreateView()或者onActivityCreated()中恢复。

 

Activity与Fragment的最大不同点是它们如何被保存在各自的返回栈中。Activity被停止的时候,系统会将它放入返回栈中,然而一个Fragment被activity管理着,只有在移除Fragment的事务中明确通过调用addToBackStack()方法请求,Fragment才会被放入返回栈中。

 

其他情况下,管理一个Fragment的生命与管理activity的生命周期一样。

 

与activity生命周期的协调

 

Activity的生命周期影响Fragment的生命周期。例如,当activity接收到onPause()调用是,在这个activity中的Fragment也会接收到。

 

onAttach()

Fragment与一个activity关联的时候调用(Activity对象在此处被传入)

onCreateView()

创建Fragment视图层的时候调用

onActivityCreated()

activityonCreate()方法返回时被调用

onDestroyView()

当视图层相关的Fragment被移除时调用

onDetach()

Fragmentactivity失去关联的时候调用

 

 

当activity到达Resume状态,就可以从activity添加、移除Fragment。但是,只有activity在Resume状态时,Fragment的生命周期才可以独立的变化。

 

当activity离开Resume状态,Fragment又要将其生命周期与activity关联

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值