1 Activity
与 Fragment
之间通信
Activity
传递数据到 Fragment
Fragment
传递数据到 Activity
2 Fragment
与 Fragment
之间通信
Activity
与 Fragment
之间通信Activity
如何传递数据到 Fragment
使用Fragment.setArguments(bundle)
,把bundle
设置到fragment
,在Fragment
中onCreateView()
中取出。
Activity
中动态添加Fragment
时使用Fragment
的setArguments(bundle)
方法把bundle
对象传递给fragment
// 步骤1:获取FragmentManager
FragmentManager fragmentManager = getSupportFragmentManager();
// 步骤2:获取FragmentTransaction
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
// 步骤3:创建需要添加的Fragment
ActivityAndFragmentDataCommunicationFragment fragment = new ActivityAndFragmentDataCommunicationFragment();
// 步骤4:创建Bundle对象
// 作用:存储数据,并传递到Fragment中
Bundle bundle = new Bundle();
// 步骤5:往bundle中添加数据
bundle.putString("message", editText.getText().toString());
// 步骤6:把数据设置到Fragment中
fragment.setArguments(bundle);
// 步骤7:动态添加fragment
// 即将创建的fragment添加到Activity布局文件中定义的占位符中(FrameLayout)
fragmentTransaction.add(R.id.fragment, fragment);
fragmentTransaction.commit();
Fragment
中接收Activity
传递的Bundle
对象 //1.获取Bundle
Bundle bundle = getArguments();
//2. 判断bundle对象是否包含key值为message的数据
if (bundle != null && bundle.containsKey("message")) {
//3. 从bundle中获取key值为message的数据
String message = bundle.getString("message");
}
可以在fragment
中设置public
方法,因Activity
持有fragment
对象,故可以直接调用fragment
中的方法。
Fragment
如何传递数据给 Activity
通过接口回调,在 Activity
中把接口引用传递给 Fragement
,
public interface ICallBack {
/**
* 向Activity传递数据
*/
void sendDataToActivity(String string);
/**
* 从Activity获取数据
*/
String getDataFromActivity();
}
Fragment
中接收 ICallBack
引用 private ICallBack callBack;
//设置 ICallBack接口回调 方法
public void sendCallBack(ICallBack callBack) {
this.callBack = callBack;
}
@Override
public void onClick(View v) {
int id = v.getId();
if (id == R.id.get) {
getDataFromActivity();
} else if (id == R.id.commit) {
sendDataToActivity();
}
}
/**
* 向Activity传递数据
* 调用接口sendDataToActivity()方法,使Activity接收回调
*/
private void sendDataToActivity() {
if (callBack != null) {
callBack.sendDataToActivity(editText.getText().toString());
}
}
/**
* 从Activity获取数据
* 调用接口getDataFromActivity()方法,使Activity接收回调
*/
private void getDataFromActivity() {
if (callBack != null) {
String data = callBack.getDataFromActivity();
textView.setText(data);
}
}
Activity
中将 callBack
引用设置给fragment
ActivityAndFragmentDataCommunicationFragment fragment = new ActivityAndFragmentDataCommunicationFragment();
//设置fragment数据回调
fragment.sendCallBack(new ICallBack() {
@Override
public void sendDataToActivity(String string) {
// 当fragment中调用callBack.sendDataToActivity()方法时会回调到该方法,
// 即把fragment中数据传递到Activity
textView.setText(string);
}
@Override
public String getDataFromActivity() {
// 当fragment中调用callBack.getDataFromActivity()方法时会回调到该方法,
// 该方法return 的数据fragment会获取到,即Fragment通过此方式获取到Activity中数据
return editText.getText().toString();
}
});
根据上述说明可以看到fragment
如何从Activity
中获取数据以及fragment
如何将数据传递给Activity
(此处不仅仅传递和获取了数据,而且直接调用Activity中的方法)。
Fragment
与 Fragment
之间通信因为每个FragmentManager
都会实现 FragmentResutOwner
。这意味着FragmentManager
可以充当Fragment result
的集中存储区。此更改通过设置Fragment
结果并监听这些结果,而不要Fragment
直接引用彼此,让单独的Fragment
相互通信。
如需将数据从Fragment B
传回到 Fragment A
,要先在接收结果的 Fragment A
上设置结果监听器。在Fragment A
的 FragmentManager
上调用setFragmetResultListener()
API,如下所示:
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getParentFragmentManager().setFragmentResultListener("key", this, new FragmentResultListener() {
@Override
public void onFragmentResult(@NonNull String key, @NonNull Bundle bundle) {
// We use a String here, but any type that can be put in a Bundle is supported
String result = bundle.getString("bundleKey");
// Do something with the result...
}
});
}
Fragment B
使用 FragmentManager
将数据发送到 Fragment A
在生成结果的 Fragment B
中,必须使用相同的requestKey
在同一FragmentManager
上设置结果。可以使用 setFragmentReusult()
API来完成此操作:
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Bundle result = new Bundle();
result.putString("bundleKey", "result");
getParentFragmentManager().setFragmentResult("requestKey", result);
}
});
然后,在值为STARTED
后,Fragment A
便会收到结果并执行监听器回调。
对于一个key
,只能有一个监听器和一个结果。如果对同一key
多次调用setResult()
,则系统会将 Fragment B
从返回堆栈退出之前的最近 result
发送给Fragment A
。如果设置的结果没有相应的监听器来接收,则结果会存储在FragmentManager
中,知道设置一个具有相同key
的监听器。监听器的Fragment
必须为 STARTED
,然后该Fragment
才能收到结果。监听器收到结果并触发onFragmentResult()
回调后,结果会被清除。这种行为有两个主要影响:
Fragment
只有在被弹出栈顶且未 STARTED
之后才会受到结果Fragment
为STARTED
,则系统会立即触发监听器的回调。Fragment
为DESTROYED
之后,就无法再对该Fragment
设置监听器。Fragment
和子级Fragment
之间传递结果如需将结果从子级Fragment
传递到父级Fragment
,父级Fragment
在调用setFragmentResultListener()
时应该使用getChildFragmentManager()
而不是getParentFragmentManager()
。
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// We set the listener on the child fragmentManager
getChildFragmentManager().setFragmentResultListener("key", this, new FragmentResultListener() {
@Override
public void onFragmentResult(@NonNull String key, @NonNull Bundle bundle) {
String result = bundle.getString("bundleKey");
// Do something with the result..
}
});
}
子级 Fragment 可以使用 FragmentManager 将结果发送到其父级 Fragment。
子级Fragment在其FragmentManager上设置结果。然后,当父级Fragment为STARTED时便会收到结果:
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Bundle result = new Bundle();
result.putString("bundleKey", "result");
// The child fragment needs to still set the result on its parent fragment manager
getParentFragmentManager().setFragmentResult("requestKey", result);
}
});