`
hulianwang2014
  • 浏览: 686470 次
文章分类
社区版块
存档分类
最新评论
  • bcworld: 排版成这样,一点看的欲望都没有了
    jfinal

Fragment 和 FragmentActivity的使用

 
阅读更多

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

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


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

  1. publicclassTextFragmentextendsFragment{
  2. privateStringmMsg;
  3. publicvoidsetMessage(Stringmessage){
  4. this.mMsg=message;
  5. }
  6. @Override
  7. publicViewonCreateView(LayoutInflaterinflater,ViewGroupcontainer,
  8. BundlesavedInstanceState){
  9. //TODOAuto-generatedmethodstub
  10. finalContextcontext=getActivity();
  11. FrameLayoutroot=newFrameLayout(context);
  12. root.setBackgroundColor(Color.YELLOW);
  13. TextViewtv=newTextView(context);
  14. tv.setText(mMsg);
  15. tv.setGravity(Gravity.CENTER);
  16. root.addView(tv,newFrameLayout.LayoutParams(
  17. ViewGroup.LayoutParams.FILL_PARENT,ViewGroup.LayoutParams.FILL_PARENT));
  18. returnroot;
  19. }
  20. }

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

























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

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

2.重写我们自己的FragmentActivity.

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

  1. publicclassDoorFragmentActivityextendsFragmentActivity{
  2. publicstaticfinalStringFRAG_SMS="sms_list_frag";
  3. publicstaticfinalStringFRAG_TEXT="text_frag";
  4. privateFragmentmSMSFragment;
  5. privateFragmentmTextFragment;
  6. privateFragmentManagermFragMgr;
  7. privateButtonmMenuBtn;
  8. @Override
  9. protectedvoidonCreate(BundlesavedInstanceState){
  10. //TODOAuto-generatedmethodstub
  11. super.onCreate(savedInstanceState);
  12. setContentView(R.layout.door_fragment_activity_layout);
  13. mFragMgr=getSupportFragmentManager();
  14. mMenuBtn=(Button)findViewById(R.id.door_menu_btn);
  15. mMenuBtn.setOnClickListener(newOnClickListener(){
  16. @Override
  17. publicvoidonClick(Viewv){
  18. //TODOAuto-generatedmethodstub
  19. showFragments(FRAG_TEXT,true);
  20. }
  21. });
  22. mMenuBtn.setOnLongClickListener(newOnLongClickListener(){
  23. @Override
  24. publicbooleanonLongClick(Viewv){
  25. //TODOAuto-generatedmethodstub
  26. returnfalse;
  27. }
  28. });
  29. initFragments();
  30. showFragments(FRAG_SMS,false);
  31. }
  32. privatevoidinitFragments(){
  33. mSMSFragment=newSMSListFragment();
  34. TextFragmenttextfrag=newTextFragment();
  35. textfrag.setMessage("这是菜单界面");
  36. mTextFragment=textfrag;
  37. }
  38. privatevoidshowFragments(Stringtag,booleanneedback){
  39. FragmentTransactiontrans=mFragMgr.beginTransaction();
  40. if(needback){
  41. trans.setCustomAnimations(R.anim.frag_enter,
  42. R.anim.frag_exit);
  43. trans.add(R.id.door_root_content_fl,getFragmentByTag(tag),tag);
  44. trans.addToBackStack(tag);
  45. }else{
  46. trans.replace(R.id.door_contents_fl,getFragmentByTag(tag),tag);
  47. }
  48. trans.commit();
  49. }
  50. privateFragmentgetFragmentByTag(Stringtag){
  51. if(FRAG_SMS.equals(tag)){
  52. returnmSMSFragment;
  53. }
  54. if(FRAG_TEXT.equals(tag)){
  55. returnmTextFragment;
  56. }
  57. returnnull;
  58. }
  59. }

  • 首先我们获取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中去即 viewgroup.addView(fragment.onCreateView());

未解决问题: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. publicclassSMSListFragmentextendsListFragment{
  2. privateConversationListAdaptermAdapter;
  3. privateConversationQuerymQuery;
  4. privatelongstartTime;
  5. @Override
  6. publicvoidonCreate(BundlesavedInstanceState){
  7. //TODOAuto-generatedmethodstub
  8. super.onCreate(savedInstanceState);
  9. mAdapter=newConversationListAdapter(getActivity());
  10. mQuery=newConversationQuery(getActivity().getContentResolver());
  11. }
  12. @Override
  13. publicvoidonActivityCreated(BundlesavedInstanceState){
  14. //TODOAuto-generatedmethodstub
  15. super.onActivityCreated(savedInstanceState);
  16. setListAdapter(mAdapter);
  17. }
  18. @Override
  19. publicvoidonStart(){
  20. //TODOAuto-generatedmethodstub
  21. super.onStart();
  22. startAsyncQuery();
  23. }
  24. @Override
  25. publicvoidonStop(){
  26. //TODOAuto-generatedmethodstub
  27. super.onStop();
  28. mAdapter.getCursor().close();
  29. mAdapter.changeCursor(null);
  30. }
  31. publicvoidstartAsyncQuery(){
  32. startTime=System.currentTimeMillis();
  33. mQuery.startQuery(1,null,Conversation.sAllThreadsUri,
  34. Conversation.ALL_THREADS_PROJECTION,null,null,
  35. Conversation.CONVERSATION_ORDER);
  36. }
  37. privatefinalclassConversationQueryextendsAsyncQueryHandler{
  38. publicConversationQuery(ContentResolvercr){
  39. super(cr);
  40. //TODOAuto-generatedconstructorstub
  41. }
  42. @Override
  43. protectedvoidonQueryComplete(inttoken,Objectcookie,Cursorcursor){
  44. //TODOAuto-generatedmethodstub
  45. System.out.println("conversationcursorsize:"
  46. +cursor.getCount());
  47. mAdapter.changeCursor(cursor);
  48. Toast.makeText(
  49. getActivity(),
  50. "查询短信会话个数:"+cursor.getCount()+",花费"
  51. +(System.currentTimeMillis()-startTime)+"ms",
  52. Toast.LENGTH_LONG).show();
  53. }
  54. }
  55. }
代码中可以知道和使用普通的ListActivity完全没区别,

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

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

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

onStart()中,开启查询

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

4.主页面的布局文件:

  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <FrameLayoutxmlns: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. <LinearLayout
  7. android:layout_width="match_parent"
  8. android:layout_height="match_parent"
  9. android:orientation="vertical">
  10. <FrameLayout
  11. android:id="@+id/door_contents_fl"
  12. android:layout_width="match_parent"
  13. android:layout_height="0dp"
  14. android:layout_weight="1"/>
  15. <LinearLayout
  16. android:layout_width="match_parent"
  17. android:layout_height="55dp"
  18. android:orientation="horizontal">
  19. <Button
  20. android:id="@+id/door_menu_btn"
  21. android:layout_width="match_parent"
  22. android:layout_height="match_parent"
  23. android:gravity="center"
  24. android:text="菜单"/>
  25. </LinearLayout>
  26. </LinearLayout>
  27. </FrameLayout>
5.运行效果图:

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics