Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android - How to pass data from activity to fragment? [duplicate]

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.

like image 892
navid abutorab Avatar asked Aug 25 '16 05:08

navid abutorab


5 Answers

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.

like image 186
pooja Avatar answered Oct 22 '22 01:10

pooja


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...

like image 42
Balflear Avatar answered Oct 22 '22 02:10

Balflear


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
  }

}
like image 32
Pavneet_Singh Avatar answered Oct 22 '22 02:10

Pavneet_Singh


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.

like image 26
matheszabi Avatar answered Oct 22 '22 01:10

matheszabi


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

like image 45
tpk Avatar answered Oct 22 '22 03:10

tpk