一、簡介
在進行Android開發過程中我們知道Activity的重要性,但是自android3.0之后,android中出現的Fragment重要性其實不亞于Activity,今天簡單的介紹一下Fragment之間進行數據傳遞的三種方式。
二、準備工作
step 1:創建一個Activity,命名為MainActivity,對應的布局文件如下(只截取核心部分):
<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:創建兩個Fragment分別為MenuFragment和MainFragment,對應的布局如下:
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="根據條目改變內容"
android:layout_centerInParent="true"/>
step3:兩個Fragment里面各自將布局引進(onCreateView()方法中)(具體代碼請參考源碼),需要注意的是MenuFragment里面是一個ListView,這里手動添加了5個數據填充進去;
step4:在MainActivity的onCreate()方法中引入這兩個Fragment:
MenuFragment menuFragment = new MenuFragment();
MainFragment mainFragment = new MainFragment();
//將上面的兩個Fragment添加進來
getSupportFragmentManager().beginTransaction().replace(R.id.fl_menu, menuFragment, "menuFragment").commit();
getSupportFragmentManager().beginTransaction().replace(R.id.fl_main, mainFragment, "mainFragment").commit();
需要展示的界面如下:
以上準備工作完畢!
三、三種數據傳遞方式的相關操作
需求:我們點擊上面圖片中展示的對應的條目數據,讓右側(黃色按鈕)對應的文本數據更換成條目展示的文本,例如:我點擊左側第4個條目,右側按鈕文本立馬更改成“這是第4條數據”,從而實現Fragment之間數據的傳遞。下面開始介紹三種方法實現Fragment之間數據的傳遞。
方法一:
- 1、在MainFragment中設置一個setData()方法,在方法中設置更改按鈕名稱;
//MainFragment.java文件中
public void setData(String string) {
bt_main.setText(string);
}
- 2、在MenuFragment中的ListView條目點擊事件中通過標簽獲取到MainFragment,并調用對應的setData()方法,將數據設置進去,從而達到數據傳遞的目的。
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));
}
});
只需上面區區兩步即可達到數據傳遞的目的。
方法二:
采取接口回調的方式進行數據傳遞。
- step1: 在Menuragment中創建一個接口以及接口對應的set方法:
//MenuFragment.java文件中
public interface OnDataTransmissionListener {
public void dataTransmission(String data);
}
public void setOnDataTransmissionListener(OnDataTransmissionListener mListener) {
this.mListener = mListener;
}
- step2: 在MenuFragment中的ListView條目點擊事件中進行接口進行接口回調
//MenuFragment.java文件中
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
/**
* 方法二:采取接口回調的方式進行數據傳遞
*/
if (mListener != null) {
mListener.dataTransmission(mDatas.get(position));
}
}
});
- step3: 在MainActivity中根據menuFragment獲取到接口的set方法,在這個方法中進行進行數據傳遞,具體如下:
//在MainActivity.java中
menuFragment.setOnDataTransmissionListener(new MenuFragment.OnDataTransmissionListener() {
@Override
public void dataTransmission(String data) {
mainFragment.setData(data); //注:對應的mainFragment此時應該要用final進行修飾
}
});
通過上面的三步也可以輕松做到Fragment數據之間的傳遞。
方法三:
使用三方開源框架:EventBus
那么問題來了:EventBus是個啥東西???
簡單來說,EventBus是一款針對Android優化的發布/訂閱(publish/subscribe)事件總線。主要功能是替代Intent,Handler,BroadCast在Fragment,Activity,Service,線程之間傳遞消息。簡化了應用程序內各組件間、組件與后臺線程間的通信。優點是開銷小,代碼更優雅,以及將發送者和接收者解耦。比如請求網絡,等網絡返回時通過Handler或Broadcast通知UI,兩個Fragment之間需要通過Listener通信,這些需求都可以通過EventBus實現。
下面我們就用EventBus來實現以下Fragment之間的數據傳遞:
- step1:引入EventBus
compile 'org.greenrobot:eventbus:3.0.0'
- step2:注冊事件接收者
這里MainFragment是要接收MenuFragment發送來的數據,所以我們在MainFragment中的onCreateView()方法中進行注冊:
EventBus.getDefault().register(this);
- step3:發送事件
注:發送事件之前其實還有一步定義事件類型,這里我們傳遞的數據只有一個類型,所以這一步取消了。
MenuFragment發送數據給MainFragment,所以我們在MenuFragment中將要傳遞的數據進行發送事件操作:
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中我們接收來自MenuFragment傳遞過來的數據,并進行對應的處理(注:EventBus 3.0版本這一步必須要寫注解@Subscribe (與2.4版本有所區別)):
@Subscribe
public void onEvent(String data) {
bt_main.setText(data);
}
通過上面這一步即可完成數據之間的傳遞,需要注意的是在銷毀的時候我們要注銷事件接收。
- step5:注銷事件接收
//MainFragment.java中
@Override
public void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
以上五步完成了Fragment之間的數據傳遞,看似比上面兩個方法要復雜的多,但當我們涉及到復雜的Fragment之間數據傳遞(例如Fragment中嵌套多層Fragment)時,就會體會到EventBus的爽快之處~~~這里不進行贅述了。
四、總結
對于以上三種方法,各自有各自的優點,我們可以根據實際需求采用對應的方法;對于EventBus使用有不明白的地方,這里推薦一片博客供大家學習參考:http://gold.xitu.io/entry/570ae5668ac247004c3128a4
以上三個方法的講解源碼鏈接如下:
【源碼連接】https://github.com/Reign9201/datatransmission