两个片段之间的基本通信

我有一个activity - MainActivity 。 在这个Activity我有两个fragments ,这两个fragments都是在xml中声明创build的。

我正在尝试将用户input的文本String传递给Fragment B的文本视图。 然而这certificate是非常困难的。 有谁知道我可以做到这一点?

我知道一个片段可以使用getActivity()获取对它的活动的引用。 所以我猜我会从那里开始?

看看Android deverlopers页面: http : //developer.android.com/training/basics/fragments/communicating.html#DefineInterface

基本上,你在你的Fragment A中定义了一个接口,让你的Activity实现该接口。 现在你可以调用Fragment中的接口方法,你的Activity将会收到事件。 现在在你的活动中,你可以调用你的第二个片段来更新接收到的值的文本视图

你的活动实现你的界面(见下面的片段A)

 public class YourActivity implements FragmentA.TextClicked{ @Override public void sendText(String text){ // Get Fragment B FraB frag = (FragB) getSupportFragmentManager().findFragmentById(R.id.fragment_b); frag.updateText(text); } } 

片段A定义了一个接口,并在需要时调用该方法

 public class FragA extends Fragment{ TextClicked mCallback; public interface TextClicked{ public void sendText(String text); } @Override public void onAttach(Activity activity) { super.onAttach(activity); // This makes sure that the container activity has implemented // the callback interface. If not, it throws an exception try { mCallback = (TextClicked) activity; } catch (ClassCastException e) { throw new ClassCastException(activity.toString() + " must implement TextClicked"); } } public void someMethod(){ mCallback.sendText("YOUR TEXT"); } @Override public void onDetach() { mCallback = null; // => avoid leaking, thanks @Deepscorn super.onDetach(); } } 

片段B有一个公开的方法来处理文本

 public class FragB extends Fragment{ public void updateText(String text){ // Here you have it } } 

考虑我的2片段A和B,假设我需要将数据从B传递给A.

然后在B中创build一个接口,并将数据传递给主活动。 创build另一个接口并将数据传递给片段A.

分享一个小例子:

片段A看起来像

 public class FragmentA extends Fragment implements InterfaceDataCommunicatorFromActivity { public InterfaceDataCommunicatorFromActivity interfaceDataCommunicatorFromActivity; String data; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // TODO Auto-generated method stub return super.onCreateView(inflater, container, savedInstanceState); } @Override public void updateData(String data) { // TODO Auto-generated method stub this.data = data; //data is updated here which is from fragment B } @Override public void onAttach(Activity activity) { // TODO Auto-generated method stub super.onAttach(activity); try { interfaceDataCommunicatorFromActivity = (InterfaceDataCommunicatorFromActivity) activity; } catch (ClassCastException e) { throw new ClassCastException(activity.toString() + " must implement TextClicked"); } } } 

FragmentB看起来像

 class FragmentB extends Fragment { public InterfaceDataCommunicator interfaceDataCommunicator; @Override public void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); // call this inorder to send Data to interface interfaceDataCommunicator.updateData("data"); } public interface InterfaceDataCommunicator { public void updateData(String data); } @Override public void onAttach(Activity activity) { // TODO Auto-generated method stub super.onAttach(activity); try { interfaceDataCommunicator = (InterfaceDataCommunicator) activity; } catch (ClassCastException e) { throw new ClassCastException(activity.toString() + " must implement TextClicked"); } } } 

主要活动是

 public class MainActivity extends Activity implements InterfaceDataCommunicator { public InterfaceDataCommunicatorFromActivity interfaceDataCommunicatorFromActivity; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public void updateData(String data) { // TODO Auto-generated method stub interfaceDataCommunicatorFromActivity.updateData(data); } public interface InterfaceDataCommunicatorFromActivity { public void updateData(String data); } } 

其他的一些例子(甚至是写这篇文章的时候的文档 )都使用过时的方法。 这是一个完整的更新的例子。

在这里输入图像描述

笔记

  • 你不想让片段直接对话或交stream。 这将他们与特定的活动联系在一起,使复用变得困难。
  • 解决scheme是制作一个Activity将执行的callback监听器接口。 当片段想要发送消息到另一个片段或其父活动时,可以通过界面来完成。
  • 活动直接与其子片段公共方法通信是可以的。
  • 因此,Activity作为控制器,将消息从一个片段传递到另一个片段。

MainActivity.java

 public class MainActivity extends AppCompatActivity implements GreenFragment.OnGreenFragmentListener { private static final String BLUE_TAG = "blue"; private static final String GREEN_TAG = "green"; BlueFragment mBlueFragment; GreenFragment mGreenFragment; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // add fragments FragmentManager fragmentManager = getSupportFragmentManager(); mBlueFragment = (BlueFragment) fragmentManager.findFragmentByTag(BLUE_TAG); if (mBlueFragment == null) { mBlueFragment = new BlueFragment(); fragmentManager.beginTransaction().add(R.id.blue_fragment_container, mBlueFragment, BLUE_TAG).commit(); } mGreenFragment = (GreenFragment) fragmentManager.findFragmentByTag(GREEN_TAG); if (mGreenFragment == null) { mGreenFragment = new GreenFragment(); fragmentManager.beginTransaction().add(R.id.green_fragment_container, mGreenFragment, GREEN_TAG).commit(); } } // The Activity handles receiving a message from one Fragment // and passing it on to the other Fragment @Override public void messageFromGreenFragment(String message) { mBlueFragment.youveGotMail(message); } } 

GreenFragment.java

 public class GreenFragment extends Fragment { private OnGreenFragmentListener mCallback; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.fragment_green, container, false); Button button = v.findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String message = "Hello, Blue! I'm Green."; mCallback.messageFromGreenFragment(message); } }); return v; } // This is the interface that the Activity will implement // so that this Fragment can communicate with the Activity. public interface OnGreenFragmentListener { void messageFromGreenFragment(String text); } // This method insures that the Activity has actually implemented our // listener and that it isn't null. @Override public void onAttach(Context context) { super.onAttach(context); if (context instanceof OnGreenFragmentListener) { mCallback = (OnGreenFragmentListener) context; } else { throw new RuntimeException(context.toString() + " must implement OnGreenFragmentListener"); } } @Override public void onDetach() { super.onDetach(); mCallback = null; } } 

BlueFragment.java

 public class BlueFragment extends Fragment { private TextView mTextView; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.fragment_blue, container, false); mTextView = v.findViewById(R.id.textview); return v; } // This is a public method that the Activity can use to communicate // directly with this Fragment public void youveGotMail(String message) { mTextView.setText(message); } } 

XML

activity_main.xml中

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="16dp"> <!-- Green Fragment container --> <FrameLayout android:id="@+id/green_fragment_container" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:layout_marginBottom="16dp" /> <!-- Blue Fragment container --> <FrameLayout android:id="@+id/blue_fragment_container" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" /> </LinearLayout> 

fragment_green.xml

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:background="#98e8ba" android:padding="8dp" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/button" android:text="send message to blue" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> 

fragment_blue.xml

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:background="#30c9fb" android:padding="16dp" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/textview" android:text="TextView" android:textSize="24sp" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> 

更新

忽略这个答案。 不是不行。 但是有更好的方法可用。 而且,Android着重阻碍了片段之间的直接通信。 见官方文档 。 感谢用户@Wahib Ul Haq提示。

原始答复

那么,你可以在Fragment B中创build一个私有variables和setter,并从Fragment A本身设置值,

FragmentB.java

 private String inputString; .... .... public void setInputString(String string){ inputString = string; } 

FragmentA.java

 //go to fragment B FragmentB frag = new FragmentB(); frag.setInputString(YOUR_STRING); //create your fragment transaction object, set animation etc fragTrans.replace(ITS_ARGUMENTS) 

或者,您可以按照您的build议使用“活动”。

我最近创build了一个库,使用注释为您生成这些types的铸造样板代码。 https://github.com/zeroarst/callbackfragment

这是一个例子。 单击DialogFragment上的TextView触发DialogFragment中的MainActivity的callback,然后获取MyFagment交互的MyFagment实例。

 public class MainActivity extends AppCompatActivity implements MyFragment.FragmentCallback, MyDialogFragment.DialogListener { private static final String MY_FRAGM = "MY_FRAGMENT"; private static final String MY_DIALOG_FRAGM = "MY_DIALOG_FRAGMENT"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); getSupportFragmentManager().beginTransaction() .add(R.id.lo_fragm_container, MyFragmentCallbackable.create(), MY_FRAGM) .commit(); findViewById(R.id.bt).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { MyDialogFragmentCallbackable.create().show(getSupportFragmentManager(), MY_DIALOG_FRAGM); } }); } Toast mToast; @Override public void onClickButton(MyFragment fragment) { if (mToast != null) mToast.cancel(); mToast = Toast.makeText(this, "Callback from " + fragment.getTag() + " to " + this.getClass().getSimpleName(), Toast.LENGTH_SHORT); mToast.show(); } @Override public void onTextClicked(MyDialogFragment fragment) { MyFragment myFragm = (MyFragment) getSupportFragmentManager().findFragmentByTag(MY_FRAGM); if (myFragm != null) { myFragm.updateText("Callback from " + fragment.getTag() + " to " + myFragm.getTag()); } } 

}

你可以按照这个例子。 它演示了每次传递不同数据(编辑文本中的文本)的两个片段之间的基本通信。

https://github.com/bitsabhi/DemoFragmentCommunications