9

I need to pass data from activity to fragment. I know I can use bundle , but once I passed data,I can't send data without calling and creating fragment again.

In my activity, some thing may be changed and I need to notify my fragment for these changes without recreating fragment.

Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
navid abutorab
  • 189
  • 1
  • 2
  • 9

8 Answers8

17

Create one interface in your Activity and pass your data via the interface to the fragment. Implement that interface in your fragment to get data.

For example

MainActivity.class

public class MainActivity extends AppCompatActivity {

    DataFromActivityToFragment dataFromActivityToFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        FragmentA fr = new FragmentA();
        FragmentManager fm = getFragmentManager();
        dataFromActivityToFragment = (DataFromActivityToFragment) fr;
        FragmentTransaction fragmentTransaction = fm.beginTransaction();
        fragmentTransaction.replace(R.id.fragment_place, fr);
        fragmentTransaction.commit();


        final Handler handler = new Handler();

        final Runnable r = new Runnable() {
            public void run() {
                dataFromActivityToFragment.sendData("Hi");
            }
        };

        handler.postDelayed(r, 5000);


    }

    public interface DataFromActivityToFragment {
        void sendData(String data);
    }
}

FragmentA.class

public class FragmentA extends Fragment implements MainActivity.DataFromActivityToFragment {

    TextView text;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.content_main, null);
        text = (TextView) rootView.findViewById(R.id.fragment_text);

        return rootView;
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
    }

    @Override
    public void sendData(String data) {
        if(data != null)
        text.setText(data);
    }
}

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <LinearLayout
        android:id="@+id/fragment_place"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal">
    </LinearLayout>

</LinearLayout>

content_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/fragment_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

In above example I have taken Runnable just to send data with delay of 5 seconds after creation of fragment.

Aniruddha
  • 4,477
  • 2
  • 21
  • 39
pooja
  • 393
  • 8
  • 16
3

Fragment object is just like other objects.Like String , you can invoke methods of string object, str.charAt(0) ,str.toUpperCase() etc. Just create a function in fragment, put your code there and call the function along with values

Inside Activity {
  fragDemoObject.doWhatYouWant("this is passed as string object to fragment");
}

Inside FragmentDemo{
  void doWhatYouWant(String input){
     System.out.println(input);
    // do what else you want to do with code
  }

}
Pavneet_Singh
  • 36,884
  • 5
  • 53
  • 68
1

Actually your question is not related to:

I need to pass data from activity to fragmenet .I know I can use bundle , but one i've passed data , I cant send anymore data without calling and creating fragment once more .

The real one is this:

in my activity , some thing may be changed and I need to notify my fragment from these changes without recreating fragment.

how can I do so ?

In this case I would store the fragment in the activity as reference and I would call a function, an interface implementation inside the fragment.

Something like this:

In Activity:

SomeEventListener myFragment  ;

yourFragmentCreationMethod(){
 if(myFragment == null){
    myFragment  = new MyFragment(maybeParamsHere);
  }
}

yourNotificationMethod(){
   myFragment .onEventHappent(param);
}

// declare an interface: - separate file
public interface SomeEventListener
{
    void onEventHappent(param);
}

// implement the interface in Fragment - separate file
public class MyFragment extends Fragment implements SomeEventListener{
    // add a constructor what you like

    public void onEventHappent(param){
           /// ... your update
    }
}

The interface it will help you at testing only.

matheszabi
  • 594
  • 5
  • 16
1

The host activity can deliver messages to a fragment by capturing the Fragment instance with findFragmentById(), then directly call the fragment's public methods.

In your fragment - MyFragment, create a public method

public void myFragmentDataFromActivity(int passedDataFromActivity) {

// do your stuff

}

In your activity to pass an integer value say, 100 :

get MyFragment instance using getSupportFragmentManager or getFragmentManager by providing id/tag/position. Then call the public method in MyFragment instance.

MyFragment myFragment = (MyFragment) getSupportFragmentManager.getFragmentById(id);

myFragment.myFragmentDataFromActivity(100);

You can also use getFragmentByTag(tag), getFragments().get(position) instead of getFragmentById(id) to get fragment instance.

read more about this

mrtpk
  • 1,398
  • 4
  • 18
  • 38
1

For notify fragment with some data after it's created, can be done using some Communicator, or you can always pass the data with bundle in creation time... For example:

public interface FragmentCommunicator {

void updateDataToFragment(List<Parcelable> data);

} then in your fragment implement this interface and calling it from the activity for example as:`

Fragment fragment = mSectionsPagerAdapter.getRegisteredFragment(i);
            if (fragment instanceof FragmentCommunicator) {
                FragmentCommunicator fragmentCommunicator = (FragmentCommunicator) fragment;
                fragmentCommunicator.updateDataToFragment(data);

        }`

This should works for your case...

Kostadin Georgiev
  • 866
  • 1
  • 9
  • 23
0

try this one in Activity

fragment=new PdfFragment();
if (fragment != null) {
    FragmentManager fragmentManager = getFragmentManager();

        Bundle bundle = new Bundle();
        bundle.putString("pdf", Pdf);
    bundle.putString("flag", "0");
    fragment.setArguments(bundle);

    fragmentManager.beginTransaction().replace(R.id.container, fragment).addToBackStack(null).commit();
}

and in fragment

     Pdf = getArguments().getString("pdf");
Mr. Mad
  • 1,230
  • 1
  • 14
  • 28
0

You should declare your method as public in the fragment to update new data. Then you will call that method via fragment instance. For example, write this in your activity when getting new data:

fragmentInstance.publicMethod(newData);

Happy coding!

Na Pro
  • 715
  • 1
  • 8
  • 23
0

I have also come across the same issue, I have used singleton class to transfer data from activity to fragment (without making fragment transaction or using inteface)

class DataPersistance {


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPlace() {
        return place;
    }

    public void setPlace(String place) {
        this.place = place;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    private String name;
    private String place;
    private String type;

    private static final DataPersistance ourInstance = new DataPersistance();

    static DataPersistance getInstance() {
        return ourInstance;
    }

    private DataPersistance() {
    }
}

to set and get data

        DataPersistance.getInstance().setName(mEditText.getText().toString());
      String name =  DataPersistance.getInstance().getName();
akshay_shahane
  • 4,423
  • 2
  • 17
  • 30