自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Android Fragment之間的通訊處理

移動開發(fā) Android
Fragment是google由3.0開始加入SDK的界面解決方案,后續(xù)由谷歌團(tuán)隊(duì)維護(hù)并發(fā)行了support包以支持低版本SDK來使用Fragment。本文重點(diǎn)介紹了如何解決模塊之間的通訊的耦合問題。

Fragment是google由3.0開始加入SDK的界面解決方案。

后續(xù)由谷歌團(tuán)隊(duì)維護(hù)并發(fā)行了support包以支持低版本SDK來使用Fragment。

誰在使用Fragment

  • 網(wǎng)易新聞
  • 網(wǎng)易云音樂
  • 百度音樂
  • 多米
  • 豌豆莢
  • 小米app
  • Path
  • Pocket
  • Fuubo

###Fragment的優(yōu)點(diǎn) —————- * adding and removing Fragment可以做動畫的效果,平滑過度

  • 自動化堆棧管理,所以返回鍵可以刪除動態(tài)添加的Fragment,***銷毀Activity,無需做過多判斷

  • 集成ActionBar的標(biāo)簽,可以替代TabHost,ActivityGrounp,與谷歌設(shè)計(jì)風(fēng)格緊密結(jié)合

  • 布局更加模塊化.與原Activity中的Layout分塊化,VCBase的分塊化道理相同

  • 靈活準(zhǔn)確的生命周期去管理當(dāng)前View的狀態(tài)記錄以及橫豎屏處理

  • Fragment管理的View,可同時(shí)使用在Phone和Pad上,一份代碼兩份機(jī)器,可重用性高

  • Is a View, More than View

  • 可以從startActivityForResult中接收到返回結(jié)果,但是View不能

  • 唯一Id標(biāo)識,可以從FragmentManager中獲取id對應(yīng)的Fragment

Fragment的缺點(diǎn)

與其說是Fragment的缺點(diǎn),不如說是每個應(yīng)用程序模塊之間的通訊都面臨地耦合問題

  • Fragment之間的通訊依賴Activity使用接口管理并通知

如何解決模塊之間的通訊的耦合問題

1.使用接口,讓Activity扮演管理角色,負(fù)責(zé)分發(fā)消息到該窗口的子View

該方案的缺點(diǎn)

  • 不方便使用單元測試
  • 隨著應(yīng)用功能的增加,需要監(jiān)聽的事件越來越多,導(dǎo)致越來越多的接口聲明以及綁定

2.使用LocalBroadcastManager + IntentFilter解決不同組件通訊,Intent負(fù)責(zé)搭載數(shù)據(jù)

該方案的缺點(diǎn)

  • 不方便單元測試,需要實(shí)例化Intent,填裝Intent的數(shù)據(jù),實(shí)現(xiàn)Broadcast receivers以及再次提取Intent中的數(shù)據(jù)
  • receiver中不可做耗時(shí)操作,因?yàn)閞eciver是限時(shí)進(jìn)程,10秒后會被系統(tǒng)kill掉,如果需要做耗時(shí)操作,需另外啟Service來完成

3.EventBus

  • 消息訂閱者:Activity or Fragment等訂閱類注冊自己到EventBus中
  • 消息發(fā)布者:只負(fù)責(zé)發(fā)布消息以及消息包裝數(shù)據(jù)到EventBus
  • 回調(diào)基于命名約定以及消息包裝對象
  • 方便的單元測試

4.otto 這里不做介紹,下面有demo鏈接,基于注解的解偶通信組件

其實(shí)按照MVC的思想,Activity就真正的變成了Controler,

Activity中不涉及任何的業(yè)務(wù)邏輯的代碼,只負(fù)責(zé)分發(fā)消息到不同的子View(Fragment)。

如果希望整個應(yīng)用只有一個Activity,就需要再抽象出一層Controller,負(fù)責(zé)處理Activity與其子Controller的通訊

相關(guān)下載

項(xiàng)目

我們直接看代碼吧,因?yàn)楸磉_(dá)能力還訓(xùn)練,加上有點(diǎn)懶 ^_^ 😄

項(xiàng)目結(jié)構(gòu)

###首先是布局de代碼 - /layout/article_view.xml ** ArticleFragment.java ** 關(guān)聯(lián)的布局

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <TextView xmlns:android="http://schemas.android.com/apk/res/android" 
  3.     android:id="@+id/article" 
  4.     android:layout_width="match_parent" 
  5.     android:layout_height="match_parent" 
  6.     android:padding="16dp" 
  7.     android:textSize="18sp" > 
  8. </TextView> 

/layout/news_articles.xml ** HeadlinesFragment.java ** 關(guān)聯(lián)的布局

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  3.     android:id="@+id/fragment_container" 
  4.     android:layout_width="match_parent" 
  5.     android:layout_height="match_parent" > 
  6. </FrameLayout> 

/layout-large/new_articles.xml ** HeadlinesFragment.java ** 關(guān)聯(lián)的布局,在平板大分辨率的時(shí)候回被自動啟用

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  3.     android:layout_width="match_parent" 
  4.     android:layout_height="match_parent" 
  5.     android:orientation="horizontal" > 
  6.  
  7.     <fragment 
  8.         android:id="@+id/headlines_fragment" 
  9.         android:name="tree.love.android.fragments.HeadlinesFragment" 
  10.         android:layout_width="0dp" 
  11.         android:layout_height="match_parent" 
  12.         android:layout_weight="1" /> 
  13.  
  14.     <fragment 
  15.         android:id="@+id/article_fragment" 
  16.         android:name="tree.love.android.fragments.ArticleFragment" 
  17.         android:layout_width="0dp" 
  18.         android:layout_height="match_parent" 
  19.         android:layout_weight="2" /> 
  20.  
  21. </LinearLayout> 

#p#

MainActivity.java 首頁 -_- 其實(shí)就那么一頁 哈哈哈

  1. public class MainActivity extends FragmentActivity  implements HeadlinesFragment.OnHeadlineSelectedListener { 
  2.      
  3.     private static final String TAG = "MainActivity"
  4.  
  5.     private LocalBroadcastManager mBroadcastManager; 
  6.     private BroadcastReceiver mItemViewListClickReceiver; 
  7.      
  8.     public static final String ACTION_ITEMVIEW_LISTCLICK = "tree.love.android.fragments.itemview.listclick"
  9.      
  10.     @Override 
  11.     public void onCreate(Bundle savedInstanceState) { 
  12.         super.onCreate(savedInstanceState); 
  13.         setContentView(R.layout.news_articles); 
  14.         //如果是手機(jī)分辨率布局 
  15.         if (findViewById(R.id.fragment_container) != null) { 
  16.  
  17.             // 如果之前保存了狀態(tài),我們不需要做任何事情,否則會重復(fù)加載Fragment 
  18.             if (savedInstanceState != null) { 
  19.                 return
  20.             } 
  21.             // Create an instance of ExampleFragment 
  22.             HeadlinesFragment firstFragment = new HeadlinesFragment(); 
  23.  
  24.             //如果這個Activity被一個特殊的Intent傳遞,如果有需要,把該數(shù)據(jù)也傳給Fragment 
  25.             firstFragment.setArguments(getIntent().getExtras()); 
  26.  
  27.             // 添加該Fragment到R.id.fragment_container這個容器布局中 
  28.             getSupportFragmentManager().beginTransaction() 
  29.                     .add(R.id.fragment_container, firstFragment).commit(); 
  30.         } 
  31.     } 
  32.  
  33.     private void initBroadcastListener() { 
  34.         mBroadcastManager = LocalBroadcastManager.getInstance(this); 
  35.         IntentFilter intentFilter = new IntentFilter(); 
  36.         intentFilter.addAction(ACTION_ITEMVIEW_LISTCLICK); 
  37.         mItemViewListClickReceiver = new BroadcastReceiver() 
  38.         { 
  39.             @Override 
  40.             public void onReceive(Context context, Intent intent) 
  41.             { 
  42.                 if(intent.getAction().equals(ACTION_ITEMVIEW_LISTCLICK)) 
  43.                 { 
  44.                     Log.v(TAG, ACTION_ITEMVIEW_LISTCLICK + "," + intent.getIntExtra("position", -1)); 
  45.                 } 
  46.             } 
  47.         }; 
  48.         mBroadcastManager.registerReceiver(mItemViewListClickReceiver, intentFilter); 
  49.     } 
  50.  
  51.     /*  
  52.      * 實(shí)現(xiàn)HeadlinesFragment.OnHeadlineSelectedListener中的ListView點(diǎn)擊事件的回調(diào)接口 
  53.      */ 
  54.     public void onArticleSelected(int position) { 
  55.  
  56.         // 獲取當(dāng)前Activity是否已經(jīng)加載了ArticleFragment 
  57.         ArticleFragment articleFrag = (ArticleFragment) 
  58.                 getSupportFragmentManager().findFragmentById(R.id.article_fragment); 
  59.  
  60.         if (articleFrag != null) { 
  61.             //如果進(jìn)到這里,說明我們正在使用大屏幕布局/. 
  62.             //直接更新ArticleFragment的布局 
  63.             articleFrag.updateArticleView(position); 
  64.  
  65.         } else { 
  66.             // 我們正在使用小屏幕布局 
  67.             // 創(chuàng)建Fragment,并且傳遞參數(shù) 
  68.             ArticleFragment newFragment = new ArticleFragment(); 
  69.             Bundle args = new Bundle(); 
  70.             args.putInt(ArticleFragment.ARG_POSITION, position); 
  71.             newFragment.setArguments(args); 
  72.             FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); 
  73.  
  74.             //可定制Fragment的退出和進(jìn)入動畫 , 設(shè)置在replace or add之前 
  75.             transaction.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out, android.R.anim.fade_in, android.R.anim.fade_out); 
  76.  
  77.             // 替換R.id.fragment_container容器布局中的View 
  78.             transaction.replace(R.id.fragment_container, newFragment); 
  79.  
  80.             // 添加事物回退棧,讓系統(tǒng)管理,當(dāng)用戶點(diǎn)擊返回按鈕時(shí),銷毀當(dāng)前加載到容器布局中的ArticleFragment 
  81.             transaction.addToBackStack(null); 
  82.  
  83.             // 提交事物...不然你永遠(yuǎn)看不到ArticleFragment的出現(xiàn) ^_^ 
  84.             transaction.commit(); 
  85.         } 
  86.     } 
  87.  
  88.     /** 
  89.      * EventBus事件回掉 
  90.      * @param event 
  91.      */ 
  92.     public void onEvent(ListClickEvent event) 
  93.     { 
  94.         Log.v("""onEvent position:" + event.getPosition()); 
  95.     } 
  96.  
  97.     @Override 
  98.     protected void onStart() { 
  99.         super.onStart(); 
  100.         //在需要接收事件通知的類添加到EventBus 
  101.         EventBus.getDefault().register(this); 
  102.         //注冊Receiver 
  103.         initBroadcastListener(); 
  104.     } 
  105.  
  106.     @Override 
  107.     protected void onPause() 
  108.     { 
  109.         super.onPause(); 
  110.         //取消事件監(jiān)聽 
  111.         EventBus.getDefault().unregister(this); 
  112.         mBroadcastManager.unregisterReceiver(mItemViewListClickReceiver); 
  113.     } 

HeadlinesFragment.java ListView菜單布局

  1. public class HeadlinesFragment extends ListFragment { 
  2.     OnHeadlineSelectedListener mCallback; 
  3.  
  4.     // 通訊接口, 加載該Fragment的容器Activity必須實(shí)現(xiàn)此接口可以接收ListView的點(diǎn)擊消息 
  5.     public interface OnHeadlineSelectedListener { 
  6.         /** 當(dāng)HeadlinesFragment中的ListView點(diǎn)擊的時(shí)候觸發(fā) */ 
  7.         public void onArticleSelected(int position); 
  8.     } 
  9.  
  10.     @Override 
  11.     public void onCreate(Bundle savedInstanceState) { 
  12.         super.onCreate(savedInstanceState); 
  13.  
  14.         int layout = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ? android.R.layout.simple_list_item_activated_1 : android.R.layout.simple_list_item_1; 
  15.         setListAdapter(new ArrayAdapter<String>(getActivity(), layout, Ipsum.Headlines)); 
  16.     } 
  17.  
  18.     @Override 
  19.     public void onStart() { 
  20.         super.onStart(); 
  21.  
  22.         if (getFragmentManager().findFragmentById(R.id.article_fragment) != null) { 
  23.             getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE); 
  24.         } 
  25.     } 
  26.  
  27.     @Override 
  28.     public void onAttach(Activity activity) { 
  29.         super.onAttach(activity); 
  30.  
  31.         // 保證容器Activity實(shí)現(xiàn)了回調(diào)接口 否則拋出異常警告 
  32.         try { 
  33.             mCallback = (OnHeadlineSelectedListener) activity; 
  34.         } catch (ClassCastException e) { 
  35.             throw new ClassCastException(activity.toString()  + " must implement OnHeadlineSelectedListener"); 
  36.         } 
  37.     } 
  38.  
  39.     @Override 
  40.     public void onListItemClick(ListView l, View v, int position, long id) { 
  41.         //1.通訊方式1  接口通知Activity 
  42.         mCallback.onArticleSelected(position); 
  43.  
  44.         //2.通訊方式2  發(fā)送廣播 
  45.         Intent intent = new Intent(MainActivity.ACTION_ITEMVIEW_LISTCLICK); 
  46.         intent.putExtra("position", position); 
  47.         LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(intent); 
  48.  
  49.         //3.通訊方式3  發(fā)送事件到消息中心,由消息中心負(fù)責(zé)分發(fā)事件 
  50.         EventBus.getDefault().post(new ListClickEvent(position)); 
  51.  
  52.         // 大屏幕pad分辨率使用兩個panel的時(shí)候設(shè)置 
  53.         getListView().setItemChecked(position, true); 
  54.     } 

ArticleFragment.java 詳情頁布局。。就一個TextView啦。

  1. public class ArticleFragment extends Fragment { 
  2.  
  3.    final static String ARG_POSITION = "position"
  4.    int mCurrentPosition = -1
  5.  
  6.    @Override 
  7.    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
  8.        Bundle savedInstanceState) { 
  9.  
  10.     //回復(fù)在onSaveInstanceState中保存的是狀態(tài)數(shù)據(jù) 
  11.        if (savedInstanceState != null) { 
  12.            mCurrentPosition = savedInstanceState.getInt(ARG_POSITION); 
  13.        } 
  14.  
  15.        return inflater.inflate(R.layout.article_view, container, false); 
  16.    } 
  17.  
  18.    @Override 
  19.    public void onStart() { 
  20.        super.onStart(); 
  21.  
  22.        Bundle args = getArguments(); 
  23.        if (args != null) { 
  24.            updateArticleView(args.getInt(ARG_POSITION)); 
  25.        } else if (mCurrentPosition != -1) { 
  26.            updateArticleView(mCurrentPosition); 
  27.        } 
  28.  
  29.        EventBus.getDefault().register(this); 
  30.    } 
  31.  
  32.    @Override 
  33.    public void onPause() 
  34.    { 
  35.     super.onPause(); 
  36.     EventBus.getDefault().unregister(this); 
  37.    } 
  38.  
  39.    public void updateArticleView(int position) { 
  40.        TextView article = (TextView) getActivity().findViewById(R.id.article); 
  41.        article.setText(Ipsum.Articles[position]); 
  42.        mCurrentPosition = position; 
  43.    } 
  44.  
  45.    @Override 
  46.    public void onSaveInstanceState(Bundle outState) { 
  47.        super.onSaveInstanceState(outState); 
  48.        outState.putInt(ARG_POSITION, mCurrentPosition); 
  49.    } 
  50.  
  51.    public void onEvent(ListClickEvent event) 
  52.    { 
  53.     Log.v("ArticleFragment""onEvent" + event.getPosition()); 
  54.    } 

原文地址:http://wuyexiong.github.io/blog/2013/04/30/android-fragment-communication/

責(zé)任編輯:閆佳明 來源: wuyexiong.github.io
相關(guān)推薦

2010-04-22 17:19:49

負(fù)載均衡群集通訊

2010-04-22 17:32:21

負(fù)載均衡通訊

2023-06-27 07:31:59

微服務(wù)容錯庫重試

2016-12-02 19:00:13

Android FraAndroid

2014-07-29 09:16:14

Fragment

2013-06-04 17:23:55

Android開發(fā)移動開發(fā)Fragment

2013-07-10 15:52:17

fragmentAndroid

2023-02-03 17:28:44

HIDLAndroid硬件

2009-09-01 18:16:41

C#窗體間通訊

2021-06-16 07:21:39

AndroidAndroid系統(tǒng)多進(jìn)程通訊

2014-04-16 13:31:27

AndroidFragment多屏幕支持

2011-05-19 17:49:08

ActivityAndroid開發(fā)

2013-04-25 09:33:59

網(wǎng)絡(luò)處理器路由器交換機(jī)

2014-07-21 10:12:00

FragmentiewPagerIndcsdn app

2021-07-14 14:05:24

Fragment項(xiàng)目結(jié)構(gòu)

2010-06-18 22:42:42

智能手機(jī)平臺Android網(wǎng)秦

2010-03-04 16:08:21

Android系統(tǒng)平臺

2013-06-03 17:17:14

Android開發(fā)Android程序Android手機(jī)平板

2018-10-15 16:23:24

Android 源碼開源

2013-06-09 16:03:36

中興通訊博通蜂窩
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號