Reputation: 497
So I have viewed other questions, and I have not been able to come up with a solution. So basically, I have a parent fragment and a child fragment and I need to pass an integer to the child fragment. The child fragment is defined in the XML, so I am not able to attach a bundle as far as I know. It seems like it should be simple but I have not been able to figure it out.
Any help on how to do this would be great. Thanks!
Upvotes: 14
Views: 15421
Reputation: 501
You can use a viewmodel with the scope of parent fragment to pass data:
class ParentFragment: Fragment() {
private val viewModel: MyViewModel by viewModels()
}
class ChildFragment: Fragment() {
private val viewModel: MyViewModel by viewModels({requireParentFragment()})
}
Also, if you want to pass data from child to parent, you can use Fragment Result API. Make sure, you use childFragmentManager when setting result listener.
Parent Fragment:
childFragmentManager.setFragmentResultListener("requestKey") { key, bundle ->
val result = bundle.getString("bundleKey")
}
Child Fragment:
setFragmentResult("requestKey", bundleOf("bundleKey" to result))
Upvotes: 0
Reputation: 19237
Although strictly speaking it's not answering the question, in some cases this works as well, when we actually want to pass the same arguments to the child-fragment:
class ChildFragment extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle arguments = getArguments();
if (arguments == null) {
arguments = getParentFragment().getArguments();
}
if (arguments != null) {
if (arguments.containsKey(Constants.EXTRA_FOO)) {
// use it
}
}
}
}
Upvotes: 0
Reputation: 21
You can use arguments to pass extra data to fragments. This method works in general, not only with XML params.
...
ChildFragment cf = new ChildFragment();
Bundle b = new Bundle();
b.putInt("myInt", 0);
MyData data = new MyData();
b.putSerializable("myObject", data); // Pass entire objects
cf.setArguments(b);
...
transaction.commit();
You can than obtain the data with the getArguments
interface
...
MyData data = (MyData) getArguments.getSerializable('myObject');
...
Upvotes: 1
Reputation: 2354
You can use interface for this. Create interface in your parent fragment and create it's object and getter-setter method.
interface YourListner{
void methodToPassData(Object data);
}
static YourListner listnerObj;
public void setListnerObj(YourListner listnerObj) {
this.listnerObj = listnerObj;
}
Implement it in your child fragment.
Then, add following code in parent fragment.
ChilefragmentName yourfrag=((ChilefragmentName) getSupportFragmentManager().findFragmentById(R.id.fragmentId))
if(yourfrag !=null)
{
//Set listner
yourfrag.setListnerObj((ChilefragmentName)yourfrag);
}
if(listnerObj!=null)
{
//Pass your data
listnerObj.methodToPassData(data);
}
You can handle that data in implemented method in your child fragmen.
Upvotes: 6
Reputation: 8283
Simple solution is to get reference on your child fragment in your parent fragment onCreateView
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View view = inflater.inflate(R.layout.parent_fragment, container, false);
YourChildFragment fragment = (YourChildFragment) getChildFragmentManager().findFragmentById(R.id.child_fragment_id);
// pass your data
fragment.setMyInt(42);
return view;
}
Upvotes: 12
Reputation: 3240
If you have some parameters to pass to fragment which is defined through XML, I think better and simple option is to add it dynamically. In that case you can pass two params, param1 and param2 to the child fragment like this:
public static YourFragment newInstance(String param1, String param2) {
YourFragment fragment = new YourFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
public YourFragment() {
// Required empty public constructor
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
The newInstance() method stores the parameters in the arguments bundle of the bundle. It will be useful when Android recreates the fragment. In that case, the parameters are retrieved in the onCreate()
method.
Upvotes: 1