今天学习下 Android中的 Fragment 和 FragmentActivity,因为没有4.0手机,平台是2.3.3 所以我是使用 v4 support 包来进行学习。

要想用Fragment 功能必须先让activity继承FragmentActivity,其原因是里面包含了Fragment运作的FragmentManager接口的实现类 FragmentManagerImpl ,由这个类管理所有Fragment的显示、隐藏


1.使用最简单的Fragment,我们只要继承Fragment就可以


1. public class TextFragment extends
2.       
3. private
4.       
5. public void
6. this.mMsg = message;  
7.     }  
8.       
9. @Override
10. public
11.             Bundle savedInstanceState) {  
12. // TODO Auto-generated method stub
13. final
14. new
15.         root.setBackgroundColor(Color.YELLOW);  
16. new
17.         tv.setText(mMsg);  
18.         tv.setGravity(Gravity.CENTER);  
19. new
20.                 ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));  
21. return
22.     }  
23.   
24. }

首先Fragment 就可以把它当作一个view , 只不过这个view 与 activity一样有了生命周期函数


Fragment 和 FragmentActivity的使用_ide






Fragment.onCreateView() 函数就是用于生成这个Fragment布局的view的,类似baseadapter.getView()

这样一个包含一个TextView的简单布局就完成了。

2.重写我们自己的FragmentActivity.

这里面主要要通过FragmentManager 来进行Fragment的添加和删除:




1. public class DoorFragmentActivity extends
2.   
3. public static final String FRAG_SMS = "sms_list_frag";  
4. public static final String FRAG_TEXT = "text_frag";  
5.       
6. private
7. private
8. private
9.       
10. private
11.       
12. @Override
13. protected void
14. // TODO Auto-generated method stub
15. super.onCreate(savedInstanceState);  
16.         setContentView(R.layout.door_fragment_activity_layout);  
17.         mFragMgr = getSupportFragmentManager();  
18.         mMenuBtn = (Button) findViewById(R.id.door_menu_btn);  
19. new
20.               
21. @Override
22. public void
23. // TODO Auto-generated method stub
24. true);  
25.             }  
26.         });  
27. new
28.               
29. @Override
30. public boolean
31. // TODO Auto-generated method stub
32.                   
33. return false;  
34.             }  
35.         });  
36.         initFragments();  
37. false);  
38.     }  
39.       
40. private void
41. new
42. new
43. "这是 菜单界面");  
44.         mTextFragment = textfrag;  
45.           
46.     }  
47.       
48. private void showFragments(String tag, boolean
49.         FragmentTransaction trans = mFragMgr.beginTransaction();  
50. if(needback){  
51.             trans.setCustomAnimations(R.anim.frag_enter,    
52.                     R.anim.frag_exit);  
53.             trans.add(R.id.door_root_content_fl, getFragmentByTag(tag), tag);  
54.             trans.addToBackStack(tag);  
55. else{  
56.             trans.replace(R.id.door_contents_fl, getFragmentByTag(tag), tag);  
57.         }  
58.         trans.commit();  
59.     }  
60.       
61. private
62. if(FRAG_SMS.equals(tag)){  
63. return
64.         }  
65. if(FRAG_TEXT.equals(tag)){  
66. return
67.         }  
68. return null;  
69.     }  
70. }


  • 首先我们获取FragmentManager实现:直接调用 FragmentActivity.getSupportFragmentManager(),看源码可以知道这返回的是FragmentManager内部定义的实现类FragmentManagerImpl。
  • 我们获取了FragmentManagerImpl后我们其实不咋操作这个类,只调用FragmentManager.beginTransation(),这个获取FragmentTransation接口的实现类(里面具体是BackStackRecord类的实例),我们关于Fragment的所有操作都是通过它来完成的,因为没仔细研究,我只了解直接自己在代码里面定义Fragment而没有在xml里面写(xml写觉得有点别扭)

我们主要通过 FragmentTransation的一些方法来处理Fragment的:

1) trans.add(fragment, tag);  这个实际是 containerViewId = 0 调用的3)
2) trans.add(containerViewId, fragment);  这个实际是 tag = null 调用的 3)
3) trans.add(containerViewId, fragment, tag);  如果containerViewId != 0实际上调用的是获取到

   fragment的 onCreateView方法返回的view 并加入到containerViewId这个viewgroup中去即               

未解决问题:containerViewId = 0 的时候代表什么??

4) trans.replace(containerViewId, fragment)  一样是null tag调用 5)
5) trans.replace(containerViewId, fragment, tag)  这个一样是添加一个fragment到对应的container中去,只不过比add多了一步对相同containerViewId中已有的fragment检索,进行removeFragment操作,再去添加这个新来的fragment

6) trans.addToBackStack(tag); 如果你的fragment对于back键有类似activity的回退响应,就要记得把它加入到里面去,trans里面模拟了栈,但是我的回退没有响应我设置的exit anim 这个无语还没解决

3.再使用下ListFragment,我这里写的是SMSListFragment继承了ListFragment:



1. public class SMSListFragment extends
2.       
3. private
4. private
5. private long
6.       
7. @Override
8. public void
9. // TODO Auto-generated method stub
10. super.onCreate(savedInstanceState);  
11. new
12. new
13.     }  
14.       
15. @Override
16. public void
17. // TODO Auto-generated method stub
18. super.onActivityCreated(savedInstanceState);  
19.         setListAdapter(mAdapter);  
20.     }  
21.       
22. @Override
23. public void
24. // TODO Auto-generated method stub
25. super.onStart();  
26.         startAsyncQuery();  
27.     }  
28.       
29. @Override
30. public void
31. // TODO Auto-generated method stub
32. super.onStop();  
33.         mAdapter.getCursor().close();  
34. null);  
35.     }  
36.       
37. public void
38.         startTime = System.currentTimeMillis();  
39. 1, null, Conversation.sAllThreadsUri,  
40. null, null,  
41.                 Conversation.CONVERSATION_ORDER);  
42.     }  
43.       
44. private final class ConversationQuery extends
45.   
46. public
47. super(cr);  
48. // TODO Auto-generated constructor stub
49.         }  
50.   
51. @Override
52. protected void onQueryComplete(int
53. // TODO Auto-generated method stub
54. "conversation cursor size : "
55.                     + cursor.getCount());  
56.             mAdapter.changeCursor(cursor);  
57.             Toast.makeText(  
58.                     getActivity(),  
59. "查询短信会话个数:" + cursor.getCount() + ",花费"
60. " ms",  
61.                     Toast.LENGTH_LONG).show();  
62.         }  
63.   
64.     }  
65.   
66. }

代码中可以知道和使用普通的ListActivity完全没区别,

onCreate()中完成自己要一次性初始的东西,我在里面主要是初始化一个adapter和一个对sms数据库的查询

在onActivityCreated()中将adapter设置给listview,这个不确定有没有更好的位置,

然后进入我们熟悉的生命周期方法:

onStart()中,开启查询

onStop()中,我们界面已经不在显示了,所以我们不关心数据库变化了,close cursor

4.主页面的布局文件:



1. <?xml version="1.0" encoding="utf-8"?>
2. <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
3. android:id="@+id/door_root_content_fl"
4. android:layout_width="match_parent"
5. android:layout_height="match_parent" >
6.   
7. <LinearLayout
8. android:layout_width="match_parent"
9. android:layout_height="match_parent"
10. android:orientation="vertical" >
11.   
12. <FrameLayout
13. android:id="@+id/door_contents_fl"
14. android:layout_width="match_parent"
15. android:layout_height="0dp"
16. android:layout_weight="1" />
17.   
18. <LinearLayout
19. android:layout_width="match_parent"
20. android:layout_height="55dp"
21. android:orientation="horizontal" >
22.   
23. <Button
24. android:id="@+id/door_menu_btn"
25. android:layout_width="match_parent"
26. android:layout_height="match_parent"
27. android:gravity="center"
28. android:text="菜单" />
29. </LinearLayout>
30. </LinearLayout>
31.   
32. </FrameLayout>

5.运行效果图:

Fragment 和 FragmentActivity的使用_ide_02