FragmentActivity
生命周期,以及所在生命周期做了什么事?
OnAttach:调用该方法时,Fragment会被连接到它的父Activity上;获取对父Activity的引用。
OnCreate:调用该方法来进行fragment的初始化;初始化Fragment
OnCreateView:一旦Fragment已被创建,要创建它自己的用户界面时调用该方法;创建、或者填充Fragment的UI,并返回它,如果这个Fragment没有UI,那么返回null
OnActivityCreated:一旦父Activity和Fragment的UI已被创建,则调用该方法;完成Fragment的初始化-尤其是那些父Activity被初始化完成后或者Fragment的View被完全填充后才能做的事情。(意味着Fragmet所在的Activity已经完成了初始化并且它的UI也已经完成构件好了)
onStart:在可见生命周期的开始时被调用;应用所有需要的UI变化,现在Fragment是可见的
onResume:在活动生命周期的开始时被调用;恢复所有暂停的Fragment需要的UI更新,线程或者进程,但在非活动状态它是暂停的
onPause:在活动生命周期结束时被调用;当activity不是活动的前台activity时,需要暂停UI的更新、挂起线程或者暂停那些不需要更新的CPU的集中处理。由于调用这个方法后,进程可能被终止,所以要保存所有的编辑和状态改变信息。
onSaveInstanceState:在活动生命周期结束时调用,调用该方法保存UI的状态变化;将UI的状态改变信息保存到saveInstanceState中,这个bundle会被传递到onCreate、onCreateView和onActivityCreate(如果它的父Activity被终止并且重新启动)方法中。
OnStop:在可见生命周期结束时调用该方法;当Fragment不可见时,暂停其余的UI更新、挂起线程或者暂停不在需要的处理。
onDestroyView:当Fragment的View被分离时,调用该方法;清除相关的view
onDestroy:在整个生命周期结束时调用;消除所以的资源,包括结束线程和关闭数据库连接等。
onDetach:当Fragmet从它的父Activity上分离时,调用该方法
场景演示 : 切换到该Fragment
onAttach
onCreate
onCreateView
onActivityCreated
onStart
onResume
屏幕灭掉:
onPause
onSaveInstanceState
onStop
屏幕解锁
onStart
onResume
切换到其他Fragment:
onPause
onStop
onDestroyView
切换回本身的Fragment:
onCreateView
onActivityCreated
onStart
onResume
回到桌面
onPause
onSaveInstanceState
onStop
回到应用
onStart
onResume
退出应用
onPause
onStop
onDestroyView
onDestroy
onDetach
操作总结:
- 从主acitivity中查找Fragment对象:
- 首先要获取一个FragmentManager对象,因为查找过程是基于该对象操作的。
- 使用方法findFragmentById和findFragmentByTag;
下面对上述两个方法进行说明:
当使用findFragmentById时,有两种可能,当Fragment是直接在xml中创建的时候,findFragmentById(int id)中的参数id为Fragment的资源标识符;当Fragment是嵌入在布局中的时候,findFragmentById(int id)中的参数id为布局的资源标识符。
当使用findFragmentByTag时,使用该方法查找时,前提时,在使用FragmentTransaction添加Fragment时需要指定Fragment的TAG。
- Fragment之间的交互
思路:Fragment之间的不能直接交互,在交互式,需要activity作为桥梁,采用fragment-activitiy-fragment的方式进行
1. 为了允许一个Fragment和它的Activity进行交互,你可以在Fragment类中定义一个接口,然后在Activity中实现它。Fragment在它的onAttach()生命周期方法中捕捉这个接口的实现,并且之后可以调用接口方法来达到和Activity交互的目的。
例如:
1. public class HeadlinesFragment extends ListFragment {
2. OnHeadlineSelectedListener mCallback;
3.
4. // Container Activity must implement this interface
5. public interface OnHeadlineSelectedListener {
6. public void onArticleSelected(int position);
7. }
8.
9. @Override
10. public void onAttach(Activity activity) {
11. super.onAttach(activity);
12.
13. // This makes sure that the container activity has implemented
14. // the callback interface. If not, it throws an exception
15. try {
16. mCallback = (OnHeadlineSelectedListener) activity;
17. } catch (ClassCastException e) {
18. throw new ClassCastException(activity.toString()
19. + " must implement OnHeadlineSelectedListener");
20. }
21. }
22.
23. ...
24. }
- 现在,Fragment可以通过调用onArticleSelected()方法(或者其他接口中的方法)、使用OnHeadlineSelectedListener接口的实例mCallback向activity交付信息
例如,当用户在一个列表上点击时将调用下面的方法。Fragment使用回调函数接口来向父类activity交付事件。
1. @Override
2. public void onListItemClick(ListView l, View v, int position, long id) {
3. // Send the event to the host activity
4. mCallback.onArticleSelected(position);
5. }
- 为了从Fragment中接收事件回调函数,持有它的activity必须实现在Fragment类中定义的接口。
例如,下面的activity实现了上述例子的接口。
1. public static class MainActivity extends Activity
2. implements HeadlinesFragment.OnHeadlineSelectedListener{
3. ...
4.
5. public void onArticleSelected(int position) {
6. // The user selected the headline of an article from the HeadlinesFragment
7. // Do something here to display that article
8. }
9. }
- 主activity可以通过Fragment实例、使用findFragmentById()向Fragment交付信息,然后直接调用Fragment的公共方法。
例如,像上面演示的activity可以包含另一个Fragment来显示上述回调函数返回的数据。在这种情况下,activity可以向另一个显示它们的Fragment传递回调函数中接收的信息。
1. public static class MainActivity extends Activity
2. implements HeadlinesFragment.OnHeadlineSelectedListener{
3. ...
4.
5. public void onArticleSelected(int position) {
6. // The user selected the headline of an article from the HeadlinesFragment
7. // Do something here to display that article
8.
9. ArticleFragment articleFrag = (ArticleFragment)
10. getSupportFragmentManager().findFragmentById(R.id.article_fragment);
11.
12. if (articleFrag != null) {
13. // If article frag is available, we're in two-pane layout...
14.
15. // Call a method in the ArticleFragment to update its content
16. articleFrag.updateArticleView(position);
17. } else {
18. // Otherwise, we're in the one-pane layout and must swap frags...
19.
20. // Create fragment and give it an argument for the selected article
21. ArticleFragment newFragment = new ArticleFragment();
22. Bundle args = new Bundle();
23. args.putInt(ArticleFragment.ARG_POSITION, position);
24. newFragment.setArguments(args);
25.
26. FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
27.
28. // Replace whatever is in the fragment_container view with this fragment,
29. // and add the transaction to the back stack so the user can navigate back
30. transaction.replace(R.id.fragment_container, newFragment);
31. transaction.addToBackStack(null);
32.
33. // Commit the transaction
34. transaction.commit();
35. }
36. }
37. }