0

I've searched for "setTargetFragment" and read the existing posts for answers, such as:

Communication between two fragments - which is right way?

Communicate between fragment and fragment dialog

Android - getTargetFragment and setTargetFragment - What are they used for

I am going through Big Nerd Ranch's "Android Programming" and have a question about communications between fragments. Specifically, in chapter 12 a DialogFragment is used to reset the date of a "crime" depending on screen size:

public class CrimeFragment extends Fragment {

...

            if (ScreenSize < 2080 ) {
                DatePickerFragment dialog =  DatePickerFragment
                        .newInstance(mCrime.getDate());
                dialog.setTargetFragment(CrimeFragment.this, REQUEST_DATE);
                dialog.show(manager, DIALOG_DATE);
            } else {
                date = mCrime.getDate();
                id = mCrime.getId();
                Intent intent = new Intent(getContext(), DatePickerActivity.class);
                intent.putExtra(EXTRA_DATE, date);
                startActivityForResult(intent, REQUEST_DATE);
            }

The DatePickerFragment is created below from a call in DatePickerActivity:

public class DatePickerActivity extends SingleFragmentActivity {
           private final String TAG = "DatePickerActivity";
           private static final int REQUEST_DATE = 0;

           @Override
           protected Fragment createFragment() {
               Intent intent = getIntent();
               Date date = (Date) intent.getSerializableExtra(CrimeFragment.EXTRA_DATE);
               return DatePickerFragment.newInstance(date);
           }
       }

newInstance:

public class DatePickerFragment extends DialogFragment {

...

       public static DatePickerFragment newInstance(Date date){
           Bundle args = new Bundle();
           args.putSerializable(EXTRA_DATE, date);
           DatePickerFragment fragment = new DatePickerFragment();
           fragment.setArguments(args);
           return fragment;
       }

onClick is supposed to send the date in the Dialog is supposed to be sent back to the calling function CrimeFragment, but it isn't because the calling fragment is not set, so getTargetFragment == null as seen in the code from DatePickerFragment below:

          public void onClick(View v) {
              int year = mDatePicker.getYear();
              int month = mDatePicker.getMonth();
              int day = mDatePicker.getDayOfMonth();
              Date date = new GregorianCalendar(year, month, day).getTime();
              sendResult(Activity.RESULT_OK, date);
              }
          });
         return v;
       }

            private void sendResult(int resultCode, Date date){

                if(getTargetFragment() == null){
                    Log.d(TAG + "/sendResult", "getTargetFragment = null");
                    Log.d(TAG + "/sendResult", "getTargetFragment actual value: "   + String.valueOf(getTargetFragment()));
                    return;
                }
                Log.d(TAG + "/sendResult", "getTargetFragment = "   + String.valueOf(getTargetFragment()));
                Intent intent = new Intent();
                intent.putExtra(EXTRA_DATE, date);
                getTargetFragment().onActivityResult(getTargetRequestCode(), resultCode, intent);
            }

LogCat output shows that the getTargetFragment is not set:

DatePickerFragment/sendResult: getTargetFragment = null
DatePickerFragment/sendResult: getTargetFragment actual value: null

So, I tried setting the setting the calling frament in DatePickerActivity as shown below, but this fails:

         //return DatePickerFragment.newInstance(date);
        DatePickerFragment fragment =  DatePickerFragment
                .newInstance(date);
        fragment.setTargetFragment(CrimeFragment, REQUEST_DATE);
        return fragment;

This results in an error: Error:(29, 36) error: cannot find symbol variable CrimeFragment.

Any ideas as to why setTargetFragment isn't set?

Jeff
  • 431
  • 4
  • 16

1 Answers1

0

I do not have the book you're referencing, so I can't look at the examples in their original form, but I have to say that they appear to be rather confusing.

The documentation for setTargetFragment() says this:

This may be used, for example, if this fragment is being started by another, and when done wants to give a result back to the first.

So, to use this method effectively, you must have two fragments (a "target" and something that will deliver results to the target). In any case where you have two fragments and you want one to be able to send messages to the other, you could theoretically use setTargetFragment() to accomplish this. Whether or not that is a best practice is a different discussion.

As for the code you've tried to write:

DatePickerFragment fragment =  DatePickerFragment.newInstance(date);
fragment.setTargetFragment(CrimeFragment, REQUEST_DATE);
return fragment;
Error:(29, 36) error: cannot find symbol variable CrimeFragment

As written, there must be some variable named CrimeFragment within scope when you call fragment.setTargetFragment(). There is not, so the compiler shows this error.

In the situation where the DatePickerFragment is hosted directly inside an Activity (as opposed to being a floating dialog), there's no second fragment to be the "target", so setTargetFragment() is non-sensical.

Ben P.
  • 52,661
  • 6
  • 95
  • 123
  • Ben P., I think that you've identified the problem, that DatePickerFragment being hosted inside an Activity prevents it from being able to respond directly to the initial calling Fragment. So, I went back to the Android Developer's guide to reread https://developer.android.com/training/basics/fragments/communicating.html and think that I need to respond back through the Activity that created that Fragment. – Jeff Oct 21 '17 at 22:47