嵌套片段/活动之间的通信(双向)
Communication between nested Fragments / Activities (both ways)
所以通常在Activity + Fragment通信中,在onAttach方法中你可以将东西分配给一个上下文,比如你从回调接口定义的监听器,然后用它来通信/调用函数在底层实现 Activity.
例如:
public class TestDialogFragment extends DialogFragment {
private static final String ARGUMENT_KEYWORD = "argument_keyword";
private String keyword;
private Button okButton;
private CallbackInterface callbackInterface;
public interface CallbackInterface {
void onCallbackInvoked(String keyword);
}
public static TestDialogFragment newInstance(String keyword) {
Bundle args = new Bundle();
TestDialogFragment fragment = new TestDialogFragment();
args.putString(ARGUMENT_KEYWORD, keyword);
fragment.setArguments(args);
return fragment;
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
try {
callbackInterface = (CallbackInterface) context;
}
catch (ClassCastException e) {
throw new ClassCastException(context.toString() + " must implement TestDialogFragment.CallbackInterface");
}
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
keyword = getArguments().getString(ARGUMENT_KEYWORD);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View contentView = inflater.inflate(R.layout.dialogfragment_test, container, false);
okButton = (Button) contentView.findViewById(R.id.okButton);
okButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
callbackInterface.onCallbackInvoked(keyword);
getDialog().dismiss();
}
});
return contentView;
}
}
一切都很好,但是如果您使用嵌套片段(即使用 getSupportFragmentManager() 启动第一个片段,然后在之后使用 getChildFragmentManager())怎么办?
例如,如果我有 MainActivity -> FragmentA -> FragmentB -> FragmentC 怎么办?
有没有办法让我将 MainActivity 的上下文一直传递到 FragmentC,以便 FragmentC 可以在 MainActivity 中触发回调?
反过来呢?有没有办法可以从 MainActivity 一直调用 FragmentC 中的某些函数?或者我必须做类似 "MainActivity calls a function in FragmentA which calls the same function in FragmentB which calls the function in FragmentC that does the thing we want"?
的事情
我个人使用 EventBus 库(如 this one)以相对简洁的方式完成此操作。那将是我的第一个建议。
留在 Android 框架内:
如果您的目标是在不紧密耦合的情况下在组件之间进行通信,一种可能性是 LocalBoadcastManager
。您基本上可以重现 EventBus 的功能,但是使用起来更 cumbersome/less 方便:
- 您必须创建许多
BroadcastReceiver
class 并使用 IntentFilter
注册它们。
- 您的所有消息都已广播
Intent
s。这通常意味着大量自定义意图操作字符串会散落在代码库中。任何相关数据都必须打包到 extras 中(而使用 EventBus,您可以使用任何对象作为消息)。
你也可以构建一个类 EventBus。任何接收消息的组件都将为该消息实现一个接口,并将自己注册到一些 Singleton class。任何发送消息的人都会调用 Singleton 的方法,然后迭代所有已注册的组件以传递消息。
所以通常在Activity + Fragment通信中,在onAttach方法中你可以将东西分配给一个上下文,比如你从回调接口定义的监听器,然后用它来通信/调用函数在底层实现 Activity.
例如:
public class TestDialogFragment extends DialogFragment {
private static final String ARGUMENT_KEYWORD = "argument_keyword";
private String keyword;
private Button okButton;
private CallbackInterface callbackInterface;
public interface CallbackInterface {
void onCallbackInvoked(String keyword);
}
public static TestDialogFragment newInstance(String keyword) {
Bundle args = new Bundle();
TestDialogFragment fragment = new TestDialogFragment();
args.putString(ARGUMENT_KEYWORD, keyword);
fragment.setArguments(args);
return fragment;
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
try {
callbackInterface = (CallbackInterface) context;
}
catch (ClassCastException e) {
throw new ClassCastException(context.toString() + " must implement TestDialogFragment.CallbackInterface");
}
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
keyword = getArguments().getString(ARGUMENT_KEYWORD);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View contentView = inflater.inflate(R.layout.dialogfragment_test, container, false);
okButton = (Button) contentView.findViewById(R.id.okButton);
okButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
callbackInterface.onCallbackInvoked(keyword);
getDialog().dismiss();
}
});
return contentView;
}
}
一切都很好,但是如果您使用嵌套片段(即使用 getSupportFragmentManager() 启动第一个片段,然后在之后使用 getChildFragmentManager())怎么办?
例如,如果我有 MainActivity -> FragmentA -> FragmentB -> FragmentC 怎么办?
有没有办法让我将 MainActivity 的上下文一直传递到 FragmentC,以便 FragmentC 可以在 MainActivity 中触发回调?
反过来呢?有没有办法可以从 MainActivity 一直调用 FragmentC 中的某些函数?或者我必须做类似 "MainActivity calls a function in FragmentA which calls the same function in FragmentB which calls the function in FragmentC that does the thing we want"?
的事情
我个人使用 EventBus 库(如 this one)以相对简洁的方式完成此操作。那将是我的第一个建议。
留在 Android 框架内:
如果您的目标是在不紧密耦合的情况下在组件之间进行通信,一种可能性是 LocalBoadcastManager
。您基本上可以重现 EventBus 的功能,但是使用起来更 cumbersome/less 方便:
- 您必须创建许多
BroadcastReceiver
class 并使用IntentFilter
注册它们。 - 您的所有消息都已广播
Intent
s。这通常意味着大量自定义意图操作字符串会散落在代码库中。任何相关数据都必须打包到 extras 中(而使用 EventBus,您可以使用任何对象作为消息)。
你也可以构建一个类 EventBus。任何接收消息的组件都将为该消息实现一个接口,并将自己注册到一些 Singleton class。任何发送消息的人都会调用 Singleton 的方法,然后迭代所有已注册的组件以传递消息。