从 Activity 中调用 RecyclerView.Adapter 的 Fragment 获得 ActivityResult
get onActivityResult on Fragment from Activity that called inside RecyclerView.Adapter
好的,这是我的问题
- 我有一个包含 RecyclerView 的 Fragment,当然还有一个保存内容的适配器(称为
ApprovalCutiCardAdapter
)。
在那个 ApprovalCutiCardAdapter
里面,我在卡片上设置了 OnClickListener,当卡片被点击时它会启动一个名为 DetailApprovalCuti
的 Activity。这是我启动 activity
的代码
((Activity) MyApplication.getmContext()).startActivityForResult(detailApprovalCutiIntent, 1);
在 DetailApprovalCuti
中,我正在执行 finishActivity(1)
以获取 onActivityResult
的事件。但是该事件并没有在任何地方被调用(在承载片段的 Activity 和片段中)
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.e("result", "ApprovalIzinCutiFragment");
super.onActivityResult(requestCode, resultCode, data);
}
这是我启动 Acvitity 的代码
@Override
public void onBindViewHolder(final CutiViewHolder holder, final int position) {
....
holder.cv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent detailApprovalCutiIntent = new Intent(MyApplication.getmContext(), DetailApprovalCuti.class);
Bundle b = new Bundle();
b.putParcelable("cuti", ApprovalCutiCardAdapter.allCuti.get(position));
b.putParcelable("process_cuti", ApprovalCutiCardAdapter.allCuti.get(position).getProcessCuti());
detailApprovalCutiIntent.putExtras(b);
((Activity)MyApplication.getmContext()).startActivityForResult(detailApprovalCutiIntent,1);
}
});
....
}
这是我完成 activity
的代码
btnReject.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new AlertDialog.Builder(DetailApprovalCuti.this)
.setTitle("Peringatan")
.setMessage("Apakah anda yakin?")
.setIcon(android.R.drawable.ic_dialog_alert)
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
setResult(1);
finish();
}
}).setNegativeButton(android.R.string.no, null).show();
}
});
你的 Activity
应该由 "for-results" 片段开始 startActivityForResult(detailApprovalCutiIntent, 1);
而不是 ((Activity) MyApplication.getmContext()).startActivityForResult(detailApprovalCutiIntent, 1);
- 然后在托管片段的 Activity
您可以处理 onActivityResult
- 但随后您想将此事件传播到 Fragment
。所以你调用 super.onActivityResult(requestCode, resultCode, data);
- 你会得到类似的东西:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
}
然后在 Fragment 中你可以处理 onActivityResult
回调。
请查看这些密切相关的问题并尝试选择的答案:
我希望这能说明一些问题。
我认为您的设计不必要地复杂,并且它把 Activity、Fragment 和 RecyclerView 的适配器耦合得太紧密了。
试试这个:
- 当适配器检测到卡片上的点击时,让它将其传达给它的父级(在本例中为片段)。
- 当 Fragment 收到点击通知时,让它通知它的父级(Activity)
- 当片段通知 Activity 时,让它(Activity)用 startActivityForResult
启动新的 Activity
- 当 Activity 在 onActivityResult 中得到结果时,让它对结果做任何它需要做的事情。如果 Fragment 中需要该结果,请让它将结果传达给 Fragment。
下一个问题是Fragment和Activity之间如何通信。
"standard"的答案是创建一对接口,让Activity实现一个,Fragment实现另一个,然后使用接口方法来回调用。
这可能很难正确执行,因为 Activity 和片段必须仔细跟踪彼此的生命周期以避免崩溃。
我发现更好、更简单的解决方案是使用消息总线(例如 Otto)在它们之间传递消息。这样,Activity 和 Fragment 只需要在准备就绪时注册和注销总线,完全避免了生命周期问题。
问题是,在下一行中,您从 Activity 调用 startActivityForResult()
,这可能不是您期望的那个。
((Activity)MyApplication.getmContext()).startActivityForResult(detailApprovalCutiIntent, 1);
考虑到您的适配器是从 Fragment
设置的,您应该将上面的行修改为:
fragment.getActivity().startActivityForResult(detailApprovalCutiIntent, 1);
吸取教训
切勿使用单例,因为 Singletons are Pathological Liars。
PS: 单个实例很好,但单个实例(如全局变量)是一个糟糕的设计,必须避免。
好的,这是我的问题
- 我有一个包含 RecyclerView 的 Fragment,当然还有一个保存内容的适配器(称为
ApprovalCutiCardAdapter
)。 在那个
的代码ApprovalCutiCardAdapter
里面,我在卡片上设置了 OnClickListener,当卡片被点击时它会启动一个名为DetailApprovalCuti
的 Activity。这是我启动 activity((Activity) MyApplication.getmContext()).startActivityForResult(detailApprovalCutiIntent, 1);
在
DetailApprovalCuti
中,我正在执行finishActivity(1)
以获取onActivityResult
的事件。但是该事件并没有在任何地方被调用(在承载片段的 Activity 和片段中)@Override public void onActivityResult(int requestCode, int resultCode, Intent data) { Log.e("result", "ApprovalIzinCutiFragment"); super.onActivityResult(requestCode, resultCode, data); }
这是我启动 Acvitity 的代码
@Override public void onBindViewHolder(final CutiViewHolder holder, final int position) { .... holder.cv.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent detailApprovalCutiIntent = new Intent(MyApplication.getmContext(), DetailApprovalCuti.class); Bundle b = new Bundle(); b.putParcelable("cuti", ApprovalCutiCardAdapter.allCuti.get(position)); b.putParcelable("process_cuti", ApprovalCutiCardAdapter.allCuti.get(position).getProcessCuti()); detailApprovalCutiIntent.putExtras(b); ((Activity)MyApplication.getmContext()).startActivityForResult(detailApprovalCutiIntent,1); } }); .... }
这是我完成 activity
的代码btnReject.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { new AlertDialog.Builder(DetailApprovalCuti.this) .setTitle("Peringatan") .setMessage("Apakah anda yakin?") .setIcon(android.R.drawable.ic_dialog_alert) .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { setResult(1); finish(); } }).setNegativeButton(android.R.string.no, null).show(); } });
你的 Activity
应该由 "for-results" 片段开始 startActivityForResult(detailApprovalCutiIntent, 1);
而不是 ((Activity) MyApplication.getmContext()).startActivityForResult(detailApprovalCutiIntent, 1);
- 然后在托管片段的 Activity
您可以处理 onActivityResult
- 但随后您想将此事件传播到 Fragment
。所以你调用 super.onActivityResult(requestCode, resultCode, data);
- 你会得到类似的东西:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
}
然后在 Fragment 中你可以处理 onActivityResult
回调。
请查看这些密切相关的问题并尝试选择的答案:
我希望这能说明一些问题。
我认为您的设计不必要地复杂,并且它把 Activity、Fragment 和 RecyclerView 的适配器耦合得太紧密了。
试试这个:
- 当适配器检测到卡片上的点击时,让它将其传达给它的父级(在本例中为片段)。
- 当 Fragment 收到点击通知时,让它通知它的父级(Activity)
- 当片段通知 Activity 时,让它(Activity)用 startActivityForResult 启动新的 Activity
- 当 Activity 在 onActivityResult 中得到结果时,让它对结果做任何它需要做的事情。如果 Fragment 中需要该结果,请让它将结果传达给 Fragment。
下一个问题是Fragment和Activity之间如何通信。 "standard"的答案是创建一对接口,让Activity实现一个,Fragment实现另一个,然后使用接口方法来回调用。
这可能很难正确执行,因为 Activity 和片段必须仔细跟踪彼此的生命周期以避免崩溃。
我发现更好、更简单的解决方案是使用消息总线(例如 Otto)在它们之间传递消息。这样,Activity 和 Fragment 只需要在准备就绪时注册和注销总线,完全避免了生命周期问题。
问题是,在下一行中,您从 Activity 调用 startActivityForResult()
,这可能不是您期望的那个。
((Activity)MyApplication.getmContext()).startActivityForResult(detailApprovalCutiIntent, 1);
考虑到您的适配器是从 Fragment
设置的,您应该将上面的行修改为:
fragment.getActivity().startActivityForResult(detailApprovalCutiIntent, 1);
吸取教训
切勿使用单例,因为 Singletons are Pathological Liars。
PS: 单个实例很好,但单个实例(如全局变量)是一个糟糕的设计,必须避免。