I need to pass some data from the child fragment to the parent fragment that I will be able to read when I go back to the parent fragment. In detail:
I have a FragmentActivity that calls FragmentParent. From FragmentParent I call FragmentChild like this:
FragmentChild fragmentChild = new FragmentChild();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.frl_view_container, fragmentChild);
transaction.addToBackStack(null);
ctransaction.commit();
In FragmentChild I set a string value which I need to pass back to FragmentParent and then I return back to FragmentParent.
String result = "OK";
getFragmentManager().popBackStack();
What is the best/proper way to read the result string in FragmentParent?
Android architecture components solution:
In case you are using Android architecture components, it possible to share data between all Fragments
of an Activity
with a ViewModel
. Ensure ViewModelProviders
makes use of Activity
context to create ViewModels
.
public class SharedViewModel extends ViewModel {
private final MutableLiveData<Item> selected = new MutableLiveData<Item>();
public void select(Item item) {
selected.setValue(item);
}
public LiveData<Item> getSelected() {
return selected;
}
}
public class MasterFragment extends Fragment {
private SharedViewModel model;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
itemSelector.setOnClickListener(item -> {
model.select(item);
});
}
}
public class DetailFragment extends Fragment {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedViewModel model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
model.getSelected().observe(this, { item ->
// Update the UI.
});
}
}
Non Android architecture components solution:
You can use setTargetFragment and onActivityResult to achieve this.
Set FragmentParent instance as target fragment on FragmentChild instance i.e.
FragmentChild fragmentChild = new FragmentChild();
fragmentChild.setTargetFragment(this, FRAGMENT_CODE);
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.frl_view_container, fragmentChild);
transaction.addToBackStack(null);
transaction.commit();
In FragmentChild, wherever you are invoking the popBackStack, call onActivityResult on the set target Fragment. Use Bundle to pass on additional data.
Intent intent = new Intent();
intent.putExtra(FRAGMENT_KEY, "Ok");
getTargetFragment().onActivityResult(getTargetRequestCode(), Activity.RESULT_OK, intent);
getFragmentManager().popBackStack();
Back in FragmentParent, override the default onActivityResult method.
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode == FRAGMENT_CODE && resultCode == Activity.RESULT_OK) {
if(data != null) {
String value = data.getStringExtra(FRAGMENT_KEY);
if(value != null) {
Log.v(TAG, "Data passed from Child fragment = " + value);
}
}
}
}