14

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!

kvel
  • 497
  • 1
  • 4
  • 12
  • Send Data Through Constructor – Quick learner Aug 05 '15 at 04:21
  • @quick learner, that will not work when fragments are created by Android itself on configuration change. – Ganesh Kumar Aug 05 '15 at 04:23
  • Check out this answer, You will understand communication between Fragment - Fragment and Activity - Fragment, http://stackoverflow.com/questions/24081101/using-localbroadcastmanager-to-communicate-from-fragment-to-activity/24083101#24083101 – Umang Kothari Aug 05 '15 at 06:35

6 Answers6

12

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;
}
Stas Parshin
  • 7,973
  • 3
  • 24
  • 43
6

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.

Beena
  • 2,334
  • 24
  • 50
1

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.

Ganesh Kumar
  • 3,220
  • 1
  • 19
  • 27
1

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');
...
Joris Lamers
  • 21
  • 1
  • 2
0

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
            }
        }
    }
}
Gavriel
  • 18,880
  • 12
  • 68
  • 105
0

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))
Akn
  • 421
  • 5
  • 9