【Android】Fragment之間數(shù)據(jù)傳遞的三種方式

一、簡(jiǎn)介

在進(jìn)行Android開(kāi)發(fā)過(guò)程中我們知道Activity的重要性,但是自android3.0之后,android中出現(xiàn)的Fragment重要性其實(shí)不亞于Activity,今天簡(jiǎn)單的介紹一下Fragment之間進(jìn)行數(shù)據(jù)傳遞的三種方式。

二、準(zhǔn)備工作

step 1:創(chuàng)建一個(gè)Activity,命名為MainActivity,對(duì)應(yīng)的布局文件如下(只截取核心部分):

<FrameLayout
    android:id="@+id/fl_menu"
    android:layout_width="0dp"
    android:layout_weight="1"
    android:background="#20ff0000"
    android:layout_height="match_parent"/>
<FrameLayout
    android:id="@+id/fl_main"
    android:layout_width="0dp"
    android:layout_weight="2"
    android:background="#2500ff00"
    android:layout_height="match_parent"/>

step2:創(chuàng)建兩個(gè)Fragment分別為MenuFragment和MainFragment,對(duì)應(yīng)的布局如下: MenuFragment的核心布局:

<ListView
    android:id="@+id/lv_menu"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>
MainFragment核心布局:
<Button
    android:id="@+id/bt_main"
    android:background="#ff0"
    android:layout_width="200dp"
    android:layout_height="200dp"
    android:text="根據(jù)條目改變內(nèi)容"
    android:layout_centerInParent="true"/>

step3:兩個(gè)Fragment里面各自將布局引進(jìn)(onCreateView()方法中)(具體代碼請(qǐng)參考源碼),需要注意的是MenuFragment里面是一個(gè)ListView,這里手動(dòng)添加了5個(gè)數(shù)據(jù)填充進(jìn)去; step4:在MainActivity的onCreate()方法中引入這兩個(gè)Fragment:

MenuFragment menuFragment = new MenuFragment();
MainFragment mainFragment  = new MainFragment();
//將上面的兩個(gè)Fragment添加進(jìn)來(lái)
getSupportFragmentManager().beginTransaction().replace(R.id.fl_menu, menuFragment, "menuFragment").commit();
getSupportFragmentManager().beginTransaction().replace(R.id.fl_main, mainFragment, "mainFragment").commit();

需要展示的界面如下:

界面展示

以上準(zhǔn)備工作完畢!

三、三種數(shù)據(jù)傳遞方式的相關(guān)操作

需求:我們點(diǎn)擊上面圖片中展示的對(duì)應(yīng)的條目數(shù)據(jù),讓右側(cè)(黃色按鈕)對(duì)應(yīng)的文本數(shù)據(jù)更換成條目展示的文本,例如:我點(diǎn)擊左側(cè)第4個(gè)條目,右側(cè)按鈕文本立馬更改成“這是第4條數(shù)據(jù)”,從而實(shí)現(xiàn)Fragment之間數(shù)據(jù)的傳遞。下面開(kāi)始介紹三種方法實(shí)現(xiàn)Fragment之間數(shù)據(jù)的傳遞。

方法一:

  • 1、在MainFragment中設(shè)置一個(gè)setData()方法,在方法中設(shè)置更改按鈕名稱;
//MainFragment.java文件中
public void setData(String string) {
    bt_main.setText(string);
}
  • 2、在MenuFragment中的ListView條目點(diǎn)擊事件中通過(guò)標(biāo)簽獲取到MainFragment,并調(diào)用對(duì)應(yīng)的setData()方法,將數(shù)據(jù)設(shè)置進(jìn)去,從而達(dá)到數(shù)據(jù)傳遞的目的。
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
          MainFragment mainFragment =
               (MainFragment) getActivity()
               .getSupportFragmentManager()
               .findFragmentByTag("mainFragment");
          mainFragment.setData(mDatas.get(position));
     }
});

只需上面區(qū)區(qū)兩步即可達(dá)到數(shù)據(jù)傳遞的目的。

方法二:

采取接口回調(diào)的方式進(jìn)行數(shù)據(jù)傳遞。

  • step1: 在Menuragment中創(chuàng)建一個(gè)接口以及接口對(duì)應(yīng)的set方法:
//MenuFragment.java文件中
public interface OnDataTransmissionListener {
    public void dataTransmission(String data);
}
public void setOnDataTransmissionListener(OnDataTransmissionListener mListener) {
    this.mListener = mListener;
}
  • step2: 在MenuFragment中的ListView條目點(diǎn)擊事件中進(jìn)行接口進(jìn)行接口回調(diào)
//MenuFragment.java文件中
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
   @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        /**
         * 方法二:采取接口回調(diào)的方式進(jìn)行數(shù)據(jù)傳遞
         */
        if (mListener != null) {
            mListener.dataTransmission(mDatas.get(position));
        }
    }
});
  • step3: 在MainActivity中根據(jù)menuFragment獲取到接口的set方法,在這個(gè)方法中進(jìn)行進(jìn)行數(shù)據(jù)傳遞,具體如下:
//在MainActivity.java中
menuFragment.setOnDataTransmissionListener(new MenuFragment.OnDataTransmissionListener() {
    @Override
    public void dataTransmission(String data) {
        mainFragment.setData(data);  //注:對(duì)應(yīng)的mainFragment此時(shí)應(yīng)該要用final進(jìn)行修飾
    }
});

通過(guò)上面的三步也可以輕松做到Fragment數(shù)據(jù)之間的傳遞。

方法三: 使用三方開(kāi)源框架:EventBus 那么問(wèn)題來(lái)了:EventBus是個(gè)啥東西??? 簡(jiǎn)單來(lái)說(shuō),EventBus是一款針對(duì)Android優(yōu)化的發(fā)布/訂閱(publish/subscribe)事件總線。主要功能是替代Intent,Handler,BroadCast在Fragment,Activity,Service,線程之間傳遞消息。簡(jiǎn)化了應(yīng)用程序內(nèi)各組件間、組件與后臺(tái)線程間的通信。優(yōu)點(diǎn)是開(kāi)銷小,代碼更優(yōu)雅,以及將發(fā)送者和接收者解耦。比如請(qǐng)求網(wǎng)絡(luò),等網(wǎng)絡(luò)返回時(shí)通過(guò)Handler或Broadcast通知UI,兩個(gè)Fragment之間需要通過(guò)Listener通信,這些需求都可以通過(guò)EventBus實(shí)現(xiàn)。 下面我們就用EventBus來(lái)實(shí)現(xiàn)以下Fragment之間的數(shù)據(jù)傳遞:

  • step1:引入EventBus
compile 'org.greenrobot:eventbus:3.0.0'
  • step2:注冊(cè)事件接收者
    這里MainFragment是要接收MenuFragment發(fā)送來(lái)的數(shù)據(jù),所以我們?cè)贛ainFragment中的onCreateView()方法中進(jìn)行注冊(cè):
EventBus.getDefault().register(this);
  • step3:發(fā)送事件
    注:發(fā)送事件之前其實(shí)還有一步定義事件類型,這里我們傳遞的數(shù)據(jù)只有一個(gè)類型,所以這一步取消了。
    MenuFragment發(fā)送數(shù)據(jù)給MainFragment,所以我們?cè)贛enuFragment中將要傳遞的數(shù)據(jù)進(jìn)行發(fā)送事件操作:
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        EventBus.getDefault().post(mDatas.get(position));
    }
});
  • step4:接收消息并處理
    在MainFragment中我們接收來(lái)自MenuFragment傳遞過(guò)來(lái)的數(shù)據(jù),并進(jìn)行對(duì)應(yīng)的處理(注:EventBus 3.0版本這一步必須要寫注解@Subscribe (與2.4版本有所區(qū)別)):
@Subscribe
public void onEvent(String data) {
    bt_main.setText(data);
}

通過(guò)上面這一步即可完成數(shù)據(jù)之間的傳遞,需要注意的是在銷毀的時(shí)候我們要注銷事件接收。

  • step5:注銷事件接收
//MainFragment.java中
@Override
public void onDestroy() {
    super.onDestroy();
    EventBus.getDefault().unregister(this);
}

以上五步完成了Fragment之間的數(shù)據(jù)傳遞,看似比上面兩個(gè)方法要復(fù)雜的多,但當(dāng)我們涉及到復(fù)雜的Fragment之間數(shù)據(jù)傳遞(例如Fragment中嵌套多層Fragment)時(shí),就會(huì)體會(huì)到EventBus的爽快之處~~~這里不進(jìn)行贅述了。

四、總結(jié)

對(duì)于以上三種方法,各自有各自的優(yōu)點(diǎn),我們可以根據(jù)實(shí)際需求采用對(duì)應(yīng)的方法;對(duì)于EventBus使用有不明白的地方,這里推薦一片博客供大家學(xué)習(xí)參考:http://gold.xitu.io/entry/570ae5668ac247004c3128a4

以上三個(gè)方法的講解源碼鏈接如下:

【源碼連接】https://github.com/Reign9201/datatransmission

好了,內(nèi)容就到這了,別忘了點(diǎn)贊哦!
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,460評(píng)論 6 538
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,067評(píng)論 3 423
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事?!?“怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 177,467評(píng)論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 63,468評(píng)論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,184評(píng)論 6 410
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,582評(píng)論 1 325
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,616評(píng)論 3 444
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,794評(píng)論 0 289
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,343評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,096評(píng)論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,291評(píng)論 1 371
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,863評(píng)論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,513評(píng)論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 34,941評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 36,190評(píng)論 1 291
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,026評(píng)論 3 396
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,253評(píng)論 2 375

推薦閱讀更多精彩內(nèi)容