kvel
kvel

Reputation: 497

Android: How to send data from parent fragment to child fragment

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

Answers (6)

Akn
Akn

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

Gavriel
Gavriel

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

Joris Lamers
Joris Lamers

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

Beena
Beena

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

Stas Parshin
Stas Parshin

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

Ganesh Kumar
Ganesh Kumar

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

Related Questions