多个Fragment组件可以拼接成一个Activity,那么这些Fragment如何通信呢?例如,一个显示新闻的Activity有两个Fragment,一个显示标题列表,一个显示新闻内容,点击标题列表项的时候就去更新新闻内容。为了实现Fragment的重用,Fragment之间不应该直接通信,而应该通过Activity通信。由于Fragment并不知道自己会寄生在哪个Activity,所以Fragment不知道如何向宿主Activity发送消息。那么Fragment如何与Activity通信呢?虽然Fragment不知道自己会寄生在哪个Activity下,但是Activity知道寄生在它内部的Fragment,所以可以让Activity实现一个Fragment能够识别的接口。Fragment通过接口回调,即可向其他Fragment发送消息。

下面通过一个例子展示Fragment如何与Activity通信。

新闻列表Fragment:

1. package com.zzj.ui.activityTalkWithFragmentDemo;  
2.   
3. import android.app.Activity;  
4. import android.app.ListFragment;  
5. import android.os.Bundle;  
6. import android.view.View;  
7. import android.widget.ArrayAdapter;  
8. import android.widget.ListView;  
9.   
10. public class TitleListFragment extends ListFragment {  
11.   
12. public interface TitleClick {  
13. public void onClick(int titleIndex);  
14.     }  
15.   
16. private TitleClick titleClick;  
17.   
18. @Override  
19. public void onAttach(Activity activity) {  
20. super.onAttach(activity);  
21.   
22. if (activity instanceof TitleClick) {  
23.             titleClick = (TitleClick) activity;  
24. else {  
25. throw new RuntimeException(  
26. "TitleListFragment所在的Activity必须实现TitleClick接口!");  
27.         }  
28.     }  
29.   
30. @Override  
31. public void onActivityCreated(Bundle savedInstanceState) {  
32. super.onActivityCreated(savedInstanceState);  
33.         Bundle bundle = getArguments();  
34. "titles");  
35. new ArrayAdapter<String>(getActivity(),  
36.                 android.R.layout.simple_list_item_1, titles));  
37.     }  
38.   
39. @Override  
40. public void onListItemClick(ListView l, View v, int position, long id) {  
41.         titleClick.onClick(position);  
42.     }  
43.   
44. @Override  
45. public void onDetach() {  
46. super.onDetach();  
47. null;  
48.     }  
49.   
50. }

该Fragment无需布局文件。

 

新闻内容Fragment:

1. package com.zzj.ui.activityTalkWithFragmentDemo;  
2.   
3. import android.app.Fragment;  
4. import android.os.Bundle;  
5. import android.view.LayoutInflater;  
6. import android.view.View;  
7. import android.view.ViewGroup;  
8. import android.widget.TextView;  
9.   
10. import com.zzj.ui.R;  
11.   
12. public class ContentFragment extends Fragment {  
13. private TextView contentView;  
14.   
15. @Override  
16. public View onCreateView(LayoutInflater inflater, ViewGroup container,  
17.             Bundle savedInstanceState) {  
18.         View view = inflater.inflate(R.layout.news_fragment_content, container,  
19. false);  
20. return view;  
21.     }  
22.   
23. @Override  
24. public void onActivityCreated(Bundle savedInstanceState) {  
25. super.onActivityCreated(savedInstanceState);  
26.         contentView = (TextView) getActivity().findViewById(  
27.                 R.id.textView_content);  
28. "content"));  
29.     }  
30.   
31. /** 
32.      * 更新内容 
33.      *  
34.      * @param content 
35.      */  
36. public void updateContent(String contentText) {  
37.         contentView.setText(contentText);  
38.     }  
39. }

新闻内容Fragment布局文件:

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="vertical" >  
6.   
7. <TextView  
8. android:id="@+id/textView_content"  
9. android:layout_width="wrap_content"  
10. android:layout_height="wrap_content"  
11. android:autoLink="web" />  
12.   
13. </LinearLayout>

 

 

下面的Activity组装了上面的两个Fragment,并且实现TitleListFragment.TitleClick接口:

1. package com.zzj.ui.activityTalkWithFragmentDemo;  
2.   
3. import android.app.Activity;  
4. import android.app.FragmentTransaction;  
5. import android.os.Bundle;  
6.   
7. import com.zzj.ui.R;  
8. import com.zzj.ui.activityTalkWithFragmentDemo.TitleListFragment.TitleClick;  
9.   
10. public class ActivityTWFragment extends Activity implements TitleClick {  
11.   
12.     TitleListFragment titleList;  
13.     ContentFragment content;  
14. new String[] { "阿里上市", "百度直达号", "腾讯企业号" };  
15. new String[] { "http://www.alibaba.com",  
16. "http://www.baidu.com", "http://www.qq.com" };  
17.   
18. @Override  
19. protected void onCreate(Bundle savedInstanceState) {  
20. super.onCreate(savedInstanceState);  
21.         setContentView(R.layout.activity_talkwith_fragment);  
22.   
23.         FragmentTransaction transaction = getFragmentManager()  
24.                 .beginTransaction();  
25.   
26.         titleList = (TitleListFragment) getFragmentManager().findFragmentByTag(  
27. "title");  
28. if (titleList == null) {  
29. new TitleListFragment();  
30. new Bundle();  
31. "titles", titles);  
32. // This can only be called before the fragment has been attached to  
33. // its activity  
34.             titleList.setArguments(bundle);  
35. "title");  
36.         }  
37.         content = (ContentFragment) getFragmentManager().findFragmentByTag(  
38. "content");  
39. if (content == null) {  
40. new ContentFragment();  
41. // 初始化显示第一条内容  
42. new Bundle();  
43. "content", "http://www.alibaba.com");  
44.             content.setArguments(args);  
45. "content");  
46.         }  
47.         transaction.commit();  
48.     }  
49.   
50. @Override  
51. public void onClick(int titleIndex) {  
52.         content.updateContent(contents[titleIndex]);  
53.     }  
54. }

Activity布局文件:

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:baselineAligned="false"  
6. android:orientation="horizontal" >  
7.   
8. <FrameLayout  
9. android:id="@+id/title_list"  
10. android:layout_width="0dp"  
11. android:layout_height="match_parent"  
12. android:layout_weight="1" >  
13. </FrameLayout>  
14.   
15. <FrameLayout  
16. android:id="@+id/content"  
17. android:layout_width="0dp"  
18. android:layout_height="match_parent"  
19. android:layout_weight="2" >  
20. </FrameLayout>  
21.   
22. </LinearLayout>

效果:

 

android EventBus在Activity和Service之间传递消息 android activity和fragment通信_ide

 

温馨提示:

1.可以在Fragment中定义一些业务方法,以更好地实现重用。例子中显示新闻内容的Fragment定义了一个更新内容的方法,这样就不必在Activity中去查找显示新闻内容的TextView组件。

2.如果要向Fragment传递参数,可以调用Fragment的setArguments(Bundle args)方法,该方法必须在调用onAttach(Activity activity)方法之前调用。