天天看點

關于Fragment與Fragment、Activity通信的四種方式1.直接在一個Fragment中調用另外一個Fragment中的方法2.使用接口3.使用廣播4.Fragment直接調用Activity中的public方法

一直想總結一下Fragment與Fragment、Activity通信的問題,今天有時間一共總結了三種,權當抛磚引玉,如果大家還有更好的方式來實作Fragment和Fragment、Activity的通信,歡迎提出來,我們一起學習。好了,我們先來看看今天要實作的一個效果圖:

關于Fragment與Fragment、Activity通信的四種方式1.直接在一個Fragment中調用另外一個Fragment中的方法2.使用接口3.使用廣播4.Fragment直接調用Activity中的public方法

左邊是一個Fragment,右邊是一個Fragment,當我們點選左邊的Fragment的時候,右邊的Fragment中顯示出我們所點選的人的作品,我們就來看看怎樣實作兩個Fragment之間的通信。

1.直接在一個Fragment中調用另外一個Fragment中的方法

我們可以直接在一個Fragment中調用另外一個Fragment的公開方法,前提是要先拿到另外一個Fragment的執行個體,我們先來看看怎樣在左邊的Fragment中拿到右邊Fragment的執行個體:

ContentFragment cf = (ContentFragment) getActivity()
							.getFragmentManager().findFragmentById(
									R.id.content_fg);
					cf.showPro(name);
           

我們通過宿主Activity拿到FragmentManager,進而再拿到右邊的Fragment,然後調用右邊Fragment裡邊的showPro方法,其中要傳入的參數是左邊點選的人名,我們看看右邊Fragment中的showPro方法:

public void showPro(String key) {
		list = map.get(key);
		adapter = new ArrayAdapter<String>(getActivity(),
				android.R.layout.simple_list_item_1, list);
		lv.setAdapter(adapter);
	}
           

先根據傳進來的人名拿到該人作品的資料集,然後構造一個adapter指派給listview,很簡單吧。使用這種方式我們可以直接在一個Fragment中調用另一個Fragment的公開方法,進而實作兩個Fragment的通信。

這種方法适于那些我們在布局檔案中就已經定義了的Fragment,這種Fragment每個都有id,可以通過FragmentManager找到,但是如果我們使用了ViewPager,即每個Fragment都是動态添加進來的,這個時候我們無法通過FragmentManager獲得另外一個Fragment的執行個體,那麼該怎麼辦呢?這時我們就要用到下面這種方式了。

2.使用接口

接口可以實作兩個Fragment之間的通信,也可以實作Fragment和Activity之間的通信,這大概是用的比較多的一種方式,也是個人比較推薦的一種方式,使用接口來實作兩個Fragment之間通信,要通過宿主Activity中轉一下,如果是Fragment和宿主Activity通信則直接調用即可,我們先看看上圖中點選韓愈的時候怎麼出現他的作品。首先在左邊的Fragment中定義一個接口:

public interface showPro {
		public void showProByName(String name);
	}
           

然後定義一個接口變量:

private showPro mCallback;
           

我們要在宿主Activity中實作這個接口,這樣當Fragment調用onAttach方法時我們就可以執行個體化這個接口了:

@Override
	public void onAttach(Activity activity) {
		super.onAttach(activity);
		if (activity != null) {
			mCallback = (showPro) activity;
		}
	}
           

當mCallback執行個體化之後,那麼我們在點選韓愈的時候就可以調用這裡邊的showProByName方法了:

lv.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				TextView nameTV = (TextView) view;
				String name = nameTV.getText().toString();
				if ("韓愈".equals(name)) {
					mCallback.showProByName(name);
				}
			}
		});
           

當然,這個方法的具體實作在宿主Activity中,當宿主Activity實作了showPro接口之後,接着就要實作它裡邊的方法了:

public class MainActivity extends Activity implements showPro {

	private ContentFragment cf;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		getActionBar().hide();
		cf = (ContentFragment) getFragmentManager().findFragmentById(
				R.id.content_fg);
	}

	@Override
	public void showProByName(String name) {
		cf.showPro(name);
	}
}
           

我們在接口的方法中調用右邊Fragment中的showPro方法,并将目前人名作為參數傳入,這個方法與1中相同,我就不貼代碼了。這個方法與1中介紹的方法相比,雖然有點麻煩,但是可以有效的解決在一個Fragment中拿不到另一個Fragment執行個體的問題,具體應用場景就是ViewPager中的Fragment之間通信。

3.使用廣播

不論我們有沒有用ViewPager,都可以用廣播實作兩個Fragment之間的通信,廣播算是這裡最靈活的通信方式了,我們看看在左邊Fragment中發送廣播:

Intent intent = new Intent("showPro");
					intent.putExtra("name", name);
					LocalBroadcastManager.getInstance(getActivity())
							.sendBroadcast(intent);
           

在右邊Fragment中接收廣播:

LocalBroadcastManager localBroadcastManager = LocalBroadcastManager
				.getInstance(getActivity());
		IntentFilter intentFilter = new IntentFilter();
		intentFilter.addAction("showPro");
		BroadcastReceiver br = new BroadcastReceiver() {

			@Override
			public void onReceive(Context context, Intent intent) {
				String key = intent.getStringExtra("name");
				list = map.get(key);
				adapter = new ArrayAdapter<String>(getActivity(),
						android.R.layout.simple_list_item_1, list);
				lv.setAdapter(adapter);
			}

		};
		localBroadcastManager.registerReceiver(br, intentFilter);
           

這些都是廣播基本的使用方法,我就不啰嗦了。

個人覺得,雖然廣播用起來最友善,但是在選擇使用哪種通信方式的時候,優先選擇上面兩種,如果前兩種方式都不可以,再考慮使用廣播。

續:

之前還忽略了一種,這裡補充一下。

4.Fragment直接調用Activity中的public方法

我們也可以直接在Fragment中調用Activity中的公開方法,如下:

((MainActivity) getActivity()).showProByName(name);
           

這裡的showProByName就是我們上文貼出來的那個MainActivity中的方法。

如果大家還有更好的實作兩個Fragment通信的方式,歡迎提出來,一起學習。

本文Demo下載下傳https://github.com/lenve/fragmentMsg