Android - Gettargetfragment and Settargetfragment - What Are They Used For

Android - getTargetFragment and setTargetFragment - What are they used for

Use case = 2 fragments hosted by the same activity.

Where startActivityForResult() establishes a relationship between 2 activities, setTargetFragment() defines the caller/called relationship between 2 fragments.

setTargetFragment(target) lets the "called" fragment know where to send the result. onActivityResult() is called manually in this case.

public class Caller extends Fragment
Fragment called = Called.newInstance()
called.setTargetFragment(this)

public class Called extends DialogFragment
intent = amazingData
getTargetFragment().onActivityResult(getTargetRequestCode(), resultCode, intent)

Should we be using setTargetFragment()? I thought Fragments should not be communicating with each other

I don't think there is implicit harm in using setTargetFragment, however, I would only use it in very specific circumstances. For example, if the target fragment is only going to ever be used by the fragment (taking into account object reuse and designing your classes to be reusable when possible) and even then, sparingly.

By using them too much, you will end up with what you're seeing - confusing code that is hard to follow and maintain. On the outset, by marshaling everything through your activity you maintain a "flat" hierarchy that is simple to follow and maintain.

I think the decision to use setTargetFragment or not is a coding-style/philosophical one that, with wisdom and experience, it "feels" right or wrong. Maybe on your case, by evidence that you are questioning your older code, you are gaining that wisdom :)

how to use getTargetFragment and setTargetFragment to send result to previous fragment

Create an intent with the result and in FragmentTwo just call getTargetFragment().onActivityResult(AppConstant.FRAGMENT_CODE,Context.RESULT_OK, intent);

How to replace setTargetFragment() now that it is deprecated

Include this dependency:

implementation 'androidx.fragment:fragment-ktx:1.3.0-beta01'

Use setFragmentResultListener instead of setTargetFragment():

override fun onPreferenceStartFragment(caller: PreferenceFragmentCompat?, pref: Preference): Boolean {
val args: Bundle = pref.extras
val fragment: Fragment = supportFragmentManager.fragmentFactory.instantiate(classLoader, pref.fragment)
fragment.arguments = args
supportFragmentManager.beginTransaction().replace(R.id.settings, fragment).addToBackStack(null).commit()

supportFragmentManager.setFragmentResultListener("requestKey") { key, bundle ->
if (key == "requestKey") {
// Get result from bundle
}
}

return true
}

And in your fragment that returns a result:

// Insert result in a bundle
setFragmentResult("requestKey", bundle)

Why does Android have setTargetFragment() for communicating data back from DialogFragments?

Architectures aren't always 100% clean. Something as big as Android is written by dozens of developers, each with their own point of view. Sometimes those points differ, and sometimes that shows up in either unsuspected API calls existing or documentation not matching up.

Also, there's a difference between sibling fragments and child fragments. A fragment shouldn't know anything about its siblings. But if a fragment needs to launch another fragment and handle its result (just like it may an activity) then its perfectly acceptable for the fragment to do it directly without needing to involve its activity. That's what setTargetFragment is for.

How to set target fragment

I've resolved my problem in next way:

public class DialogFragmentB extends DialogFragment{
...
public Dialog onCreateDialog (Bundle b){
// here i create two dialogs, first dialogA and then it calls dialogB
// finally dialogB has to return his datas and datas from dialogA in fragmentA
...
public void onClick(View v){
...
FragmentManager fm = getFragmentManager();
// these two code's lines resolved my headache --------------
Fragment ft = fm.findFragmentByTag(FragmentA.FRAGMENT_A_TAG);
ft.setTargetFragment(ft, FragmentA.CODE_REQUEST);
// ----------------------------------------------------------
dialogB.dismiss();
sendResult(Activity.RESULT_OK, myData);
}
return dialogB;
}
// And here myData goes in onActivityResult in fragmentA
private void sendResult(int resultCode, MyData myData){
if(getTargetFragment() == null){
return;
}
Intent intent = new Intent();
intent.putExtra(EXTRA_DATE_2, myData);
getTargetFragment().onActivityResult(getTargetRequestCode(), resultCode, intent);
}
}

Can't set setTargetFragment to reference the calling code

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.



Related Topics



Leave a reply



Submit