get onActivityResult on Fragment from Activity that called inside RecyclerView.Adapter

南笙酒味 提交于 2019-12-08 12:07:07

问题


okay here is my problem

  1. I have a Fragment that contains RecyclerView, and of course an adapter (called ApprovalCutiCardAdapter) that hold the content.
  2. Inside that ApprovalCutiCardAdapter I set OnClickListener on the card, when Card is clicked it will launch an Activity called DetailApprovalCuti. Here is my code to launch the activity

    ((Activity) MyApplication.getmContext()).startActivityForResult(detailApprovalCutiIntent, 1);
    
  3. In DetailApprovalCuti I'm executing finishActivity(1) to get an event of onActivityResult. But that event is not being called everywhere (in Activity that host the fragment, and in the fragment)

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        Log.e("result", "ApprovalIzinCutiFragment");
        super.onActivityResult(requestCode, resultCode, data);
    }
    
  4. Here's my code to start the 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. Here's my code to finish the 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();
        }
    });
    

回答1:


The problem is that, in the following line, you're calling startActivityForResult() from an Activity which might not be the one you're expecting.

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

Considering that your adapter is set from a Fragment, you should modify the above line to:

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

Lesson learnt

Never use singletons, for Singletons are Pathological Liars.

PS: single instances are fine but singletons (like global variables) are a bad design and must be avoided.




回答2:


Your Activity should be started "for-results" by the Fragment like : startActivityForResult(detailApprovalCutiIntent, 1); instead of ((Activity) MyApplication.getmContext()).startActivityForResult(detailApprovalCutiIntent, 1);- and then in the Activity that hosts the Fragment you can handle the onActivityResult - but then you want to propagate this event to the Fragment. So you call super.onActivityResult(requestCode, resultCode, data); - you will have something like:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
   super.onActivityResult(requestCode, resultCode, data);   
}

Then in the Fragment you can handle the onActivityResult callback.

Please have a look at these closely related quested and try out the selected answers:

  • onActivityResult is not being called in Fragment
  • startActivityForResult() from a Fragment and finishing child Activity, doesn't call onActivityResult() in Fragment

I hope this sheds some light.




回答3:


I think that your design is needlessly complicated, and that it couples the Activity, the Fragment, and the RecyclerView's adapter much too tightly.

Try this instead:

  • when the adapter detects a click on a card, have it communicate that to it's parent (in this case, the Fragment).
  • when the Fragment is notified of the click, have it notify it's parent (the Activity)
  • when the Activity is notified by the Fragment, have it (the Activity) launch the new Activity with startActivityForResult
  • when the Activity gets the result in on onActivityResult have it do whatever it needs to with the result. If that result is needed in the Fragment, have it communicate the result to the Fragment.

The next question is how to communicate between the Fragment and the Activity. The "standard" answer is to create a pair of interfaces, and have the Activity implement one, and the Fragment implement the other, and then use the interface methods to call back and forth.

This can be difficult to do correctly, because the Activity and the Fragment have to track each other's lifecycles carefully in order to not crash.

I find that a better, easier solution is to use a message bus (e.g. Otto) to communicate messages between them. This way, the Activity and Fragment only need to register to and deregister from the bus when they are ready, and you completely sidestep the lifecycle issues.



来源:https://stackoverflow.com/questions/38682250/get-onactivityresult-on-fragment-from-activity-that-called-inside-recyclerview-a

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!