How to pass a variable from Activity to Fragment, and pass it back?

AndroidAndroid FragmentsAndroid Activity

Android Problem Overview


I am currently making an android app, and I want to pass a date between activity and fragment. My activity has a button, which opens the fragment: DatePickerFragment.

In my activity I show a date, which I want to modify with the fragment. So I want to pass the date to the datepicker, and send it back to the activity.

I've tried a lot of solutions, but none are working. The easy way would pass an argument, but this can't be done with fragments.

Android Solutions


Solution 1 - Android

To pass info to a fragment , you setArguments when you create it, and you can retrieve this argument later on the method onCreate or onCreateView of your fragment.

On the newInstance function of your fragment you add the arguments you wanna send to it:

/**
 * Create a new instance of DetailsFragment, initialized to
 * show the text at 'index'.
 */
public static DetailsFragment newInstance(int index) {
    DetailsFragment f = new DetailsFragment();
    // Supply index input as an argument.
    Bundle args = new Bundle();
    args.putInt("index", index);
    f.setArguments(args);
    return f;
}

Then inside the fragment on the method onCreate or onCreateView you can retrieve the arguments like this:

Bundle args = getArguments();
int index = args.getInt("index", 0);

If you want now communicate from your fragment with your activity (sending or not data), you need to use interfaces. The way you can do this is explained really good in the documentation tutorial of communication between fragments. Because all fragments communicate between each other through the activity, in this tutorial you can see how you can send data from the actual fragment to his activity container to use this data on the activity or send it to another fragment that your activity contains.

Documentation tutorial:

http://developer.android.com/training/basics/fragments/communicating.html

Solution 2 - Android

Sending data from Activity to a Fragment

Activity:

Bundle bundle = new Bundle();
String myMessage = "Stackoverflow is cool!";
bundle.putString("message", myMessage );
FragmentClass fragInfo = new FragmentClass();
fragInfo.setArguments(bundle);
transaction.replace(R.id.fragment_single, fragInfo);
transaction.commit();

Fragment:

Reading the value in fragment

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    String myValue = this.getArguments().getString("message");
    ...
    ...
    ...
}

But if you want to send values from Fragment to Activity, read the answer of jpardogo, you must need interfaces, more info: Communicating with other Fragments

Solution 3 - Android

thanks to @ρяσѕρєя K and Terry ... it helps me a lot and works perfectly

From Activity you send data with intent as:

Bundle bundle = new Bundle(); 
bundle.putString("edttext", "From Activity"); 
// set Fragmentclass Arguments
Fragmentclass fragobj = new Fragmentclass();
fragobj.setArguments(bundle);

and in Fragment onCreateView method:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    // get arguments
    String strtext = getArguments().getString("edttext");    
    return inflater.inflate(R.layout.fragment, container, false);
}

reference : Send data from activity to fragment in android

Solution 4 - Android

For all the Kotlin developers out there:

Here is the Android Studio proposed solution to send data to your Fragment (= when you create a Blank-Fragment with File -> New -> Fragment -> Fragment(Blank) and you check "include fragment factory methods").

Put this in your Fragment:

class MyFragment: Fragment {

...

    companion object {
    
            @JvmStatic
            fun newInstance(isMyBoolean: Boolean) = MyFragment().apply {
                arguments = Bundle().apply {
                    putBoolean("REPLACE WITH A STRING CONSTANT", isMyBoolean)
                }
            }
     }
}

.apply is a nice trick to set data when an object is created, or as they state here:

> Calls the specified function [block] with this value as its receiver > and returns this value.

Then in your Activity or Fragment do:

val fragment = MyFragment.newInstance(false)
... // transaction stuff happening here

and read the Arguments in your Fragment such as:

private var isMyBoolean = false

override fun onAttach(context: Context?) {
    super.onAttach(context)
    arguments?.getBoolean("REPLACE WITH A STRING CONSTANT")?.let {
        isMyBoolean = it
    }
}

To "send" data back to your Activity, simply define a function in your Activity and do the following in your Fragment:

(activity as? YourActivityClass)?.callYourFunctionLikeThis(date) // your function will not be called if your Activity is null or is a different Class

Enjoy the magic of Kotlin!

Solution 5 - Android

Use the library EventBus to pass event that could contain your variable back and forth. It's a good solution because it keeps your activities and fragments loosely coupled

https://github.com/greenrobot/EventBus

Solution 6 - Android

Sending data from Activity into Fragments linked by XML

If you create a fragment in Android Studio using one of the templates e.g. File > New > Fragment > Fragment (List), then the fragment is linked via XML. The newInstance method is created in the fragment but is never called so can't be used to pass arguments.

Instead in the Activity override the method onAttachFragment

@Override
public void onAttachFragment(Fragment fragment) {
    if (fragment instanceof DetailsFragment) {
        Bundle args = new Bundle();
        args.putInt("index", index);
        f.setArguments(args);        
     }
}

Then read the arguments in the fragment onCreate method as per the other answers

Solution 7 - Android

answering in 2021 now a days fragment has in built static methods which are used to pass arguments while creating the fragment try them future coders

when you create a fragment it has the following static method with already defined

 public static categoryfrag newInstance(String param1, String param2) {
        categoryfrag fragment = new categoryfrag();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

onCreate method in fragment receives parameters through already defined code

   public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       if (getArguments() != null) {
           mParam1 = getArguments().getString(ARG_PARAM1);
           mParam2 = getArguments().getString(ARG_PARAM2);
         //  rr=getArguments().getInt("ky");
           sn1=mParam1;
           sn2=mParam2;
       }
   }

the below code is used in activity where mostpop is the name of the fragment class if you want other datatypes modify this in-built lines or use bundle

Fragment mp=mostpop.newInstance("parameter1","parameter2");

Solution 8 - Android

You can simply instantiate your fragment with a bundle:

Fragment fragment = Fragment.instantiate(this, RolesTeamsListFragment.class.getName(), bundle);

Solution 9 - Android

Public variable declarations in classes is the easiest way:

On target class:

public class MyFragment extends Fragment {
    public MyCallerFragment caller; // Declare the caller var
...
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
           Bundle savedInstanceState) {
        // Do what you want with the vars
        caller.str = "I changed your value!";
        caller.i = 9999;
        ...
        return inflater.inflate(R.layout.my_fragment, container, false);
    }
...
}

On caller class:

public class MyCallerFragment extends Fragment {
    public Integer i; // Declared public var
    public String str; // Declared public var
        ...
            FragmentManager fragmentManager = getParentFragmentManager();
            FragmentTransaction transaction = fragmentManager.beginTransaction();

            myFragment = new MyFragment();
            myFragment.caller = this;
            transaction.replace(R.id.nav_host_fragment, myFragment)
                    .addToBackStack(null).commit();
        ...
}

If you want to use the main activity it is easy too:

On main activity class:

public class MainActivity extends AppCompatActivity {
    public String str; // Declare public var
    public EditText myEditText; // You can declare public elements too.
                                // Taking care that you have it assigned
                                // correctly.
...
}

On called class:

public class MyFragment extends Fragment {
    private MainActivity main; // Declare the activity var
...
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
           Bundle savedInstanceState) {
        // Assign the main activity var
        main = (MainActivity) getActivity();

        // Do what you want with the vars
        main.str = "I changed your value!";
        main.myEditText.setText("Wow I can modify the EditText too!");
        ...
        return inflater.inflate(R.layout.my_fragment, container, false);
    }
...
}

> Note: Take care when using events (onClick, onChanged, etc) because > you can be on a "fighting" situation where more than one assign a > variable. The result will be that the variable sometimes does not will > change or will return to the last value magically.

For more combinations use your creativity. :)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser1687114View Question on Stackoverflow
Solution 1 - AndroidjpardogoView Answer on Stackoverflow
Solution 2 - AndroidJorgesysView Answer on Stackoverflow
Solution 3 - Androidmahmoud zaherView Answer on Stackoverflow
Solution 4 - AndroidPaul SpiesbergerView Answer on Stackoverflow
Solution 5 - AndroidSemaphoreMetaphorView Answer on Stackoverflow
Solution 6 - AndroidDaleView Answer on Stackoverflow
Solution 7 - Androidsadula anudeepView Answer on Stackoverflow
Solution 8 - AndroidstefView Answer on Stackoverflow
Solution 9 - AndroidAndrésView Answer on Stackoverflow