Fragment和Activity通信以及Fragment之间通信的两种方式

Fragment之间通信很简单……这里只是提供思路,无论是Fragment和Activity还是Fragment之间,通信的原理都是如此,一通百通,后面会附上DEMO

Fragment是依附于Activity的,所以Fragment之间通信不能直接通信,必须依靠所依附的Activity。

方式1

可以通过getSupportFragmentManager()拿到FragmentManager,然后通过FragmentManager的findFragmentByTag或者findFragmentById拿到我们需要通信的Fragment(比如说在下面的DEMO中我们用的是FragmentTabHost,所以就使用findFragmentByTag拿到Fragment,如果Fragment是直接在XML中定义的,那么就使用findFragmentById拿到Fragment),然后就可以对拿到的Fragment进行各种操作了。

方式2

如果直接在Fragment里面操作其他的Fragment总归是不太好,为了降低代码之间的耦合,我们可以通过回调实现Fragment之间通信。

因为太简单了,所以直接帖代码了

 

Demo1

1 重写fragment_home.xml和fragment_message.xml(只在fragment_home和fragment_message之间通信)

fragment_home.xml

[html] view plain copy
 
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.    >  
  6.   
  7.     <TextView  
  8.           android:id="@+id/tv"  
  9.         android:layout_centerInParent="true"  
  10.         android:layout_width="wrap_content"  
  11.         android:layout_height="wrap_content"  
  12.         android:textSize="25sp"  
  13.         android:text="Fragment Home" />  
  14.   
  15.       
  16.      <Button   
  17.          android:id="@+id/btn_home"  
  18.          android:layout_below="@id/tv"  
  19.         android:layout_centerHorizontal="true"  
  20.          android:layout_width="wrap_content"  
  21.         android:layout_height="wrap_content"  
  22.         android:text="获取来自Fragment Message的数据"/>  
  23. </RelativeLayout>  

fragment_message.xml

 

 

[html] view plain copy
 
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent" >  
  5.   
  6.     <TextView  
  7.         android:id="@+id/tv"  
  8.         android:layout_width="wrap_content"  
  9.         android:layout_height="wrap_content"  
  10.         android:layout_centerInParent="true"  
  11.         android:text="Fragment Message"  
  12.         android:textSize="25sp" />  
  13.   
  14.     <Button  
  15.         android:id="@+id/btn_message"  
  16.         android:layout_width="wrap_content"  
  17.         android:layout_height="wrap_content"  
  18.         android:layout_below="@id/tv"  
  19.         android:layout_centerHorizontal="true"  
  20.         android:text="获取来自Fragment Home的数据" />  
  21.   
  22. </RelativeLayout>  

再来看看FragmentHome的代码,很简单……

 

 

[java] view plain copy
 
  1. public class FragmentHome extends Fragment {  
  2.   
  3.     @Override  
  4.     public View onCreateView(LayoutInflater inflater, ViewGroup container,  
  5.             Bundle savedInstanceState) {  
  6.   
  7.         View view = inflater.inflate(R.layout.fragment_home, null);  
  8.         setupView(view);  
  9.   
  10.         return view;  
  11.   
  12.     }  
  13.   
  14.     private void setupView(View view) {  
  15.   
  16.         Button Btn1 = (Button) view.findViewById(R.id.btn_home);// 获取按钮资源  
  17.         Btn1.setOnClickListener(new Button.OnClickListener() {// 创建监听  
  18.             public void onClick(View v) {  
  19.                 MainTab activity = ((MainTab) getActivity());  
  20.                 FragmentManager manager = activity.getSupportFragmentManager();  
  21.                 FragmentMessage fragment = (FragmentMessage) manager  
  22.                         .findFragmentByTag("tab2");  
  23.                 if (null != fragment) {  
  24.                     View vw = fragment.getView();  
  25.                     if (null != vw) {  
  26.                         TextView txt = (TextView) vw.findViewById(R.id.tv);  
  27.                         T.showShort(getActivity(), txt.getText().toString());  
  28.                     }  
  29.                 } else {  
  30.                     T.showShort(getActivity(), "FragmentMessage还未创建");  
  31.                 }  
  32.   
  33.             }  
  34.   
  35.         });  
  36.   
  37.     }  
  38. }  

这里做一下简单说明:

 

MainTab activity = ((MainTab) getActivity());得到当前绑定的Activity实例对象

FragmentManager manager = activity.getSupportFragmentManager(); 拿到FragmentManager

FragmentMessage fragment = (FragmentMessage) manager.findFragmentByTag("tab2"); 拿到需要操作的fragment ,接下来就可以对它进行各种操作了

FragmentMessage代码类似

[java] view plain copy
 
  1. public class FragmentMessage extends Fragment {  
  2.   
  3.     @Override  
  4.     public View onCreateView(LayoutInflater inflater, ViewGroup container,  
  5.             Bundle savedInstanceState) {  
  6.   
  7.         View view = inflater.inflate(R.layout.fragment_message, null);  
  8.   
  9.           
  10.   
  11.         setupView(view);  
  12.           
  13.         return view;  
  14.     }  
  15.   
  16.     private void setupView(View view) {  
  17.         Button Btn1 = (Button)view.findViewById(R.id.btn_message);//获取按钮资源      
  18.         Btn1.setOnClickListener(new Button.OnClickListener(){//创建监听      
  19.             public void onClick(View v) {      
  20.                 MainTab activity = ((MainTab) getActivity());  
  21.                 FragmentManager manager = activity.getSupportFragmentManager();  
  22.                 FragmentHome fragmentHome = (FragmentHome) manager.findFragmentByTag("tab1");  
  23.                 if (null != fragmentHome) {  
  24.                     View vw = fragmentHome.getView();  
  25.                         if (null != vw) {  
  26.                             TextView txt = (TextView) vw  
  27.                                     .findViewById(R.id.tv);  
  28.                             T.showShort(getActivity(), txt.getText().toString());    
  29.                         }  
  30.                     } else {  
  31.                         T.showShort(getActivity(), "FragmentHome还未创建");    
  32.                     }         
  33.                   
  34.             }      
  35.     
  36.         });      
  37.   
  38.     }  
  39. }  

效果图1(首次打开时点击,FragmentMessage还未创建)

 

                效果图2(切换到消息Tab,获取到了FragmentHome中TextView的值)

                效果图3(再次切换到首页Tab,获取到了FragmentMessage中TextView的值)

 

Demo2

fragment_home.xml和fragment_message.xml(只在fragment_home和fragment_message之间通信)

fragment_home.xml

 

[html] view plain copy
 
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.    >  
  6.   
  7.     <TextView  
  8.           android:id="@+id/tv"  
  9.         android:layout_centerInParent="true"  
  10.         android:layout_width="wrap_content"  
  11.         android:layout_height="wrap_content"  
  12.         android:textSize="25sp"  
  13.         android:text="Fragment Home" />  
  14.   
  15.       
  16.      <Button   
  17.          android:id="@+id/btn_home"  
  18.          android:layout_below="@id/tv"  
  19.         android:layout_centerHorizontal="true"  
  20.          android:layout_width="wrap_content"  
  21.         android:layout_height="wrap_content"  
  22.         android:text="点击把值传给Fragment Message"/>  
  23. </RelativeLayout>  

fragment_message.xml

 

 

[html] view plain copy
 
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent" >  
  5.   
  6.     <TextView  
  7.         android:id="@+id/tv"  
  8.         android:layout_width="wrap_content"  
  9.         android:layout_height="wrap_content"  
  10.         android:layout_centerInParent="true"  
  11.         android:text="Fragment Message"  
  12.         android:textSize="25sp" />  
  13.   
  14. </RelativeLayout>  

 

 

FragmentHome

[java] view plain copy
 
  1. <pre name="code" class="java">public class FragmentHome extends Fragment {  
  2.   
  3.     OnButtonclickListener mCallback;  
  4.       
  5.     @Override  
  6.     public View onCreateView(LayoutInflater inflater, ViewGroup container,  
  7.             Bundle savedInstanceState) {  
  8.           
  9.          View  view = inflater.inflate(R.layout.fragment_home, null );  
  10.           
  11.          setupView(view);  
  12.         return view;      
  13.           
  14.     }  
  15.   
  16.     private void setupView(View view) {  
  17.         Button Btn1 = (Button)view.findViewById(R.id.btn_home);//获取按钮资源      
  18.         final TextView tv = (TextView) view.findViewById(R.id.tv);  
  19.         Btn1.setOnClickListener(new Button.OnClickListener(){//创建监听      
  20.             public void onClick(View v) {      
  21.                   
  22.                 mCallback.OnButtonclicked(tv.getText().toString());  
  23.                   
  24.             }      
  25.     
  26.         });      
  27.   
  28.     }  
  29.       
  30.       
  31.     @Override  
  32.     public void onAttach(Activity activity) {  
  33.         super.onAttach(activity);  
  34.   
  35.         
  36.         try {  
  37.             mCallback = (OnButtonclickListener) activity;  
  38.         } catch (ClassCastException e) {  
  39.             throw new ClassCastException(activity.toString()  
  40.                     + " must implement OnButtonclickListener");  
  41.         }  
  42.     }  
  43.       
  44.       
  45.       
  46.   
  47.      public interface OnButtonclickListener {  
  48.            
  49.         public void OnButtonclicked(Object object);  
  50.     }  
  51.       
  52. }  



说明:首先定义接口,然后在Button的点击事件中回调

再来看看MainTab,实现 OnButtonclickListener接口,然后重写OnButtonclicked方法就可以了

 

[java] view plain copy
 
  1. @Override  
  2.     public void OnButtonclicked(Object object) {  
  3.         FragmentMessage fMessage = (FragmentMessage) getSupportFragmentManager()  
  4.                 .findFragmentByTag("tab2");  
  5.         if (fMessage != null) {  
  6.               
  7.             View vw = fMessage.getView();  
  8.             if (null != vw) {  
  9.                 TextView txt = (TextView) vw.findViewById(R.id.tv);  
  10.                 txt.setText(object.toString());  
  11.             }   
  12.   
  13.         }else {  
  14.   
  15.             T.showShort(MainTab.this, "FragmentMessage还未创建");  
  16.         }  
  17.     }  

最后看看效果

 

 

               效果图1(首次打开时点击,FragmentMessage还未创建,所以不能把FragmentHome中TextView的值传给FragmentMessage)

                效果图2(切换到消息Tab,FragmentMessage中TextView的值显示为Fragment Message)

                效果图3(再次切换到首页Tab,点击,再切换到消息Tab,可以看到FragmentHome中TextView的值已经成功传递到FragmentMessage)


Demo1下载地址:http://download.csdn.net/detail/yalinfendou/8539469

Demo2下载地址:http://download.csdn.net/detail/yalinfendou/8539655

 
0
posted @ 2016-11-30 21:07  天涯海角路  阅读(413)  评论(0)    收藏  举报