当前位置: 首页 > 科技观察

AndroidFragment之间的通信处理

时间:2023-03-17 23:52:20 科技观察

Fragment是Google从3.0开始加入到SDK中的一种接口解决方案。随后,谷歌团队维护并发布了支持包,支持低版本SDK使用Fragment。谁在用Fragment网易新闻网易云音乐百度音乐多米豌豆荚小米App路径口袋富波###Fragment的优点——————-*添加和删除Fragment可以做动画效果,平滑过多的自动化栈管理,所以返回key可以删除动态添加的Fragment,彻底销毁Activity,不用做太多的判断。集成的ActionBar标签可以替代TabHost、ActivityGroup,与Google的设计风格紧密结合。布局更加模块化。它和原来的Activity一起被分成blocks,VCBase的切分原理是一样的,灵活准确的生命周期来管理横竖屏当前View和Fragment管理的view的状态记录,在Phone和Pad上都可以使用,一码两机,复用性高是一个View,多个View可以接收到startActivityForResult的返回结果,但是View不能通过Id唯一标识,可以从FragmentManager中获取到id对应的Fragment,相互通信面临耦合问题。Fragment之间的通信依赖于Activity使用接口来管理和通知如何解决模块之间的通信耦合问题。1、使用接口,让Activity起到管理作用,负责向窗口的子View分发消息。这种方案的缺点是使用单元测试不方便。随着应用功能的增加,需要监听的事件越来越多,导致接口的声明和绑定也越来越多。2、使用LocalBroadcastManager+IntentFilter解决不同组件之间的通信,Intent负责携带数据方案的缺点是不方便单元测试。需要实例化Intent,填写Intent的数据,实现Broadcastreceivers,再次提取Intent中的数据rceiver中不能做耗时操作,因为reciver是限时进程,10秒后会被系统kill掉。如果需要执行耗时操作,则需要启动另一个Service来完成3、EventBus消息订阅者:Activity或Fragment等订阅类注册EventBus中的消息发布者:只负责发布消息和消息打包数据到EventBus基于回调关于消息包装对象的命名规范和方便的单元测试其实按照MVC的思想,Activity真正成为了一个Controller。Activity中的代码不涉及任何业务逻辑,只负责向不同的子View(Fragments)分发消息。如果想让整个应用只有一个Activity,就需要再抽象一层Controller,负责处理Activity与其子Controller之间的通信。下载EventBus项目托管EventBus-PPT【otto项目托管】(https://github.com/square/ottootto-demo项目直接看代码,因为表达能力还在训练中,是一个有点懒^_^😄项目结构###首先是布局代码-/layout/article_view.xml**ArticleFragment.java**关联布局/layout/news_articles.xml**HeadlinesFragment.java**/layout-large/new_articles.xml**HeadlinesFragment.java**平板大分辨率时自动启用关联布局#p#MainActivity.javaHomepage-_-其实只有一页哈哈publicclassMainActivityextendsFragmentActivityimplementsHeadlinesFragment.OnHeadlineSelectedListener{privatestaticfinalStringTAG="MainActivity";privateLocalBroadcastManagermBroadcastManager;privateBroadcastReceivermItemViewListClickReceiver;publicstaticfinalStringACTION_ITEMVIEW_LISTCLICK="tree.love.android.fragments.itemview.listclick";@OverridepublicvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.news_articles);//如果是手机分辨率布局if(findViewById(R.id.fragment_container)!=null){//如果之前保存过状态,我们什么都不用做,否则Fragment会被重复加载if(savedInstanceState!=null){return;}//CreateaninstanceofExampleFragmentHeadlinesFragmentfirstFragment=newHeadlinesFragment();//如果这个Activity是通过一个特殊的Intent传递的,如果需要的话,将数据传给FragmentfirstFragment.setArguments(getIntent().getExtras());//将Fragment添加到R.id.fragme的容器布局中nt_containergetSupportFragmentManager().beginTransaction().add(R.id.fragment_container,firstFragment).commit();}}privatevoidinitBroadcastListener(){mBroadcastManager=LocalBroadcastManager.getInstance(this);IntentFilterintentFilter=newIntentFilter();intentFilter.addAction(ACTION_ITEMVIEW_LISTCLICK);mItemViewListClickReceiver=newBroadcastReceiver(){@OverridepublicvoidonReceive(Contextcontext,Intentintent){if(intent.getAction().equalsACTION_ITEMVIEW_LISTCLICK)){Log.v(TAG,ACTION_ITEMVIEW_LISTCLICK+","+intent.getIntExtra("position",-1));}}};mBroadcastManager.registerReceiver(mItemViewListClickReceiver,intentFilter);}/**实现HeadlinesFragment.OnHeadlineSelectedListenerListView点击事件回调接口*/publicvoidonArticleSelected(intposition){//获取当前Activity是否加载了ArticleFragmentArticleFragmentarticleFrag=(ArticleFragment)getSupportFragmentManager().findFragmentById(R.id.article_fragment);if(articleFrag!=null){//这里如果输入,说明我们使用的是大屏布局/.//直接更新ArticleFragment的布局articleFrag.updateArticleView(position);}else{//我们使用的是小屏布局//创建一个Fragment,传入参数ArticleFragmentnewFragment=newArticleFragment();Bundleargs=newBundle();args.putInt(ArticleFragment.ARG_POSITION,position);newFragment.setArguments(args);FragmentTransactiontransaction=getSupportFragmentManager().beginTransaction();//Fragment的出入动画可以customized,Setbeforereplaceoraddtransaction.setCustomAnimations(android.R.anim.fade_in,android.R.anim.fade_out,android.R.anim.fade_in,android.R.anim.fade_out);//替换R.id。fragment_containercontainerViewtransaction.replace(R.id.fragment_container,newFragment)inthelayout;//添加东西回栈,让系统管理,当用户点击后退按钮时,销毁当前加载到的ArticleFragmenttransaction.addToBackStack(null)容器布局;//提交东西...否则永远看不到ArticleFragment的模样^_^transaction.commit();}}/***EventBus事件返回*@paramevent*/publicvoidonEvent(ListClickEventevent){Log.v("","onEventposition:"+event.getPosition());}@OverrideprotectedvoidonStart(){super.onStart();//在需要接收事件通知的类中加入EventBusEventBus.getDefault().register(this);//注册ReceiverinitBroadcastListener();}@OverrideprotectedvoidonPause(){super.onPause();//取消事件监听EventBus.getDefault().unregister(this);mBroadcastManager.unregisterReceiver(mItemViewListClickReceiver);}}HeadlinesFragment.javaListView菜单布局publicclassHeadlinesFragmenttextendsListFragment{OnHeadlineSelectedListenermCallback;//通信接口,加载Fragment的容器Activity必须实现该接口才能接收ListView点击消息publicinterfaceOnHeadlineSelectedListener{/**点击HeadlinesFragment中的ListView时触发*/publicvoidonArticleSelected(intposition);}@OverridepublicvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);intlayout=Build.VERSION.SDK_INT>=Build.VERSIONYCOMB.CODES?android.R.layout.simple_list_item_activated_1:android.R.layout.simple_list_item_1;setListAdapter(newArrayAdapter(getActivity(),layout,Ipsum.Headlines));}@OverridepublicvoidonStart(){super.onStart();if(getFragmentManager().findFragmentById(R.id.article_fragment)!=null){getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);}}@OverridepublicvoidonAttach(活动活动){super.onAttach(活动ity);//确保容器Activity实现了回调接口,否则抛出异常警告}@OverridepublicvoidonListItemClick(ListViewl,Viewv,intposition,longid){//1。通信方式1接口通知ActivitymCallback.onArticleSelected(position);//2.通信方式2发送广播Intentintent=newIntent(MainActivity.ACTION_ITEMVIEW_LISTCLICK);intent.putExtra("position",position);LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(intent);//3.通讯方式3发送事件给消息中心,消息中心负责分发事件EventBus.getDefault().post(newListClickEvent(position));//两个面板都设置时设置getListView().setItemChecked(position,true)用于大屏pad分辨率;}}ArticleFragment.java详细页面布局。只是一个文本视图。publicclassArticleFragmenttextendsFragment{finalstaticStringARG_POSITION="position";intmCurrentPosition=-1;@OverridepublicViewonCreateView(LayoutInflaterinflater,ViewGroupcontainer,BundlesavedInstanceState){//恢复在onSaveInstanceState中保存的是状态数据if(savedInstanceState!=SInull){mCurrent_Instance=SInull)StatePosition.;}returninflater.inflate(R.layout.article_view,container,false);}@OverridepublicvoidonStart(){super.onStart();Bundleargs=getArguments();if(args!=null){updateArticleView(args.getInt(ARG_POSITION)));}elseif(mCurrentPosition!=-1){updateArticleView(mCurrentPosition);}EventBus.getDefault().register(this);}@OverridepublicvoidonPause(){super.onPause();EventBus.getDefault().unregister(这);}publicvoidupdateArticleView(intposition){TextViewarticle=(TextView)getActivity().findViewById(R.id.article);article.setText(Ipsum.Articles[position]);mCurrentPosition=position;}@OverridepublicvoidonSaveInstanceState(BundleoutState){super.onSaveInstanceState(outState);outState.putInt(ARG_POSITION,mCurrentPosition);}publicvoidonEvent(ListClickEventevent){Log.v("ArticleFragment","onEvent"+event.getPosition());}原文地址:http://wuyexiong.github.io/blog/2013/04/30/android-fragment-communication/