在RecyclerView.Adapter中调用Activity的Fragment上获取onActivityResult

时间:2016-07-31 08:39:15

标签: android android-fragments native onactivityresult

好的,这是我的问题

  1. 我有一个包含RecyclerView的片段,当然还有一个包含内容的适配器(称为ApprovalCutiCardAdapter)。
  2. ApprovalCutiCardAdapter内部,我在卡片上设置了OnClickListener,当点击卡片时,它将启动一个名为DetailApprovalCuti的活动。这是我启动活动的代码

    ((Activity) MyApplication.getmContext()).startActivityForResult(detailApprovalCutiIntent, 1);
    
  3. DetailApprovalCuti我执行finishActivity(1)以获得onActivityResult的事件。但是这个事件并没有在任何地方被调用(在托管片段的活动中和片段中)

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        Log.e("result", "ApprovalIzinCutiFragment");
        super.onActivityResult(requestCode, resultCode, data);
    }
    
  4. 这是我启动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);
        }
    });
    
    ....
    }
    
  5. 这是我完成活动的代码

    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();
        }
    });
    

3 个答案:

答案 0 :(得分:1)

您的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回调。

请查看这些密切相关的问题,并尝试选择的答案:

我希望这会有所启发。

答案 1 :(得分:1)

问题在于,在以下行中,您从一个可能不是您期望的活动的活动中调用startActivityForResult()

((Activity)MyApplication.getmContext()).startActivityForResult(detailApprovalCutiIntent, 1);

考虑到您的适配器是从Fragment设置的,您应该将以上行修改为:

fragment.getActivity().startActivityForResult(detailApprovalCutiIntent, 1);

经验教训

永远不要为Singletons are Pathological Liars使用单身人士。

PS:单个实例很好,但单例(如全局变量)是一个糟糕的设计,必须避免。

答案 2 :(得分:0)

我认为你的设计是不必要的复杂,并且它将Activity,Fragment和RecyclerView的适配器耦合得太紧。

请改为尝试:

  • 当适配器检测到卡片上的点击时,让它将其传达给它的父母(在本例中为片段)。
  • 当片段被通知点击时,让它通知它的父母(活动)
  • 当片段通知活动时,让它(活动)使用startActivityForResult启动新活动
  • 当Activity在onActivityResult上获得结果时,它会对结果做任何需要的事情。如果片段中需要该结果,请将结果传递给片段。

接下来的问题是如何在Fragment和Activity之间进行通信。 “标准”答案是创建一对接口,并使Activity实现一个,而Fragment实现另一个,然后使用接口方法来回调用。

这可能很难正确执行,因为活动和片段必须仔细跟踪彼此的生命周期,以免崩溃。

我发现更好,更简单的解决方案是使用消息总线(例如Otto)在它们之间传递消息。这样,Activity和Fragment只需要在它们准备就绪时注册到总线并从总线取消注册,并且你完全回避了生命周期问题。