137

I am just trying to build a simple sample application that uses Fragments. My scenario is, I have two activities with one fragment inside each activity. The first fragment has an edittext and a button. The second fragment has a textview. When I enter a name in the edittext and click on the button, the textview in the second fragment should display the name entered in the edittext of the first fragment.

I was able to send the value from first fragment to its activity and then from that activity to second activity. Now how do I use this value inside the second fragment?

Here is the Java code:

package com.example.fragmentexample;

import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class Fragment_1 extends Fragment{

    OnFragmentChangedListener mCallback;

    // Container Activity must implement this interface
    public interface OnFragmentChangedListener {
        public void onButtonClicked(String name);
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);

        // This makes sure that the container activity has implemented
        // the callback interface. If not, it throws an exception
        try {
            mCallback = (OnFragmentChangedListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement OnHeadlineSelectedListener");
        }
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // TODO Auto-generated method stub

        View view = inflater.inflate(R.layout.fragment_fragment_1, container, false);

        final EditText edtxtPersonName_Fragment = (EditText) view.findViewById(R.id.edtxtPersonName);
        Button btnSayHi_Fragment = (Button) view.findViewById(R.id.btnSayHi);

        btnSayHi_Fragment.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub

                String name = edtxtPersonName_Fragment.getText().toString();

                FragmentManager fm = getFragmentManager();
                Fragment_2 f2 = (Fragment_2) fm.findFragmentById(R.id.fragment_content_2);

                Activity activity = getActivity();

                if(activity != null)
                {
                    Toast.makeText(activity, "Say&ing Hi in Progress...", Toast.LENGTH_LONG).show();
                }


                if(f2 != null && f2.isInLayout())
                {
                    f2.setName(name);
                }
                else
                {
                    mCallback.onButtonClicked(name);
                }
            }
        });

        return view;


    }

}

File MainActivity.Java

package com.example.fragmentexample;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;

import android.view.Choreographer.FrameCallback;
import android.view.Menu;

public class MainActivity extends Activity implements Fragment_1.OnFragmentChangedListener {

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

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

    @Override
    public void onButtonClicked(String name) {
        // TODO Auto-generated method stub

        Intent i = new Intent(this, SecondActivity.class);
        i.putExtra("", name);
        startActivity(i);
    }

}

File SecondActivity.Java

package com.example.fragmentexample;

import android.app.Activity;
import android.os.Bundle;

public class SecondActivity extends Activity{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_second);

        Bundle b = getIntent().getExtras();

        Fragment_2 f2 = new Fragment_2();
        f2.setArguments(b);
    }
}

Fragment_2.Java

package com.example.fragmentexample;

import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class Fragment_2 extends Fragment{

    View view;
    TextView txtName;


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // TODO Auto-generated method stub

        view = inflater.inflate(R.layout.fragment_fragment_2, container, false);

            // Exception at this line
        String name = getArguments().getString("message");
        txtName = (TextView) view.findViewById(R.id.txtViewResult);
        txtName.setText(name);

        return view;
    }

    @Override
    public void onAttach(Activity activity) {
        // TODO Auto-generated method stub
        super.onAttach(activity);
    }

    public void setName(String name)
    {
        txtName.setText("Hi " + name);
    }

}

I get the following exception:

04-16 18:10:24.573: E/AndroidRuntime(713): FATAL EXCEPTION: main
04-16 18:10:24.573: E/AndroidRuntime(713): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.fragmentexample/com.example.fragmentexample.SecondActivity}: android.view.InflateException: Binary XML file line #8: Error inflating class fragment
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1815)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1831)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.ActivityThread.access$500(ActivityThread.java:122)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1024)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.os.Handler.dispatchMessage(Handler.java:99)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.os.Looper.loop(Looper.java:132)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.ActivityThread.main(ActivityThread.java:4123)
04-16 18:10:24.573: E/AndroidRuntime(713):  at java.lang.reflect.Method.invokeNative(Native Method)
04-16 18:10:24.573: E/AndroidRuntime(713):  at java.lang.reflect.Method.invoke(Method.java:491)
04-16 18:10:24.573: E/AndroidRuntime(713):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
04-16 18:10:24.573: E/AndroidRuntime(713):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
04-16 18:10:24.573: E/AndroidRuntime(713):  at dalvik.system.NativeStart.main(Native Method)
04-16 18:10:24.573: E/AndroidRuntime(713): Caused by: android.view.InflateException: Binary XML file line #8: Error inflating class fragment
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:688)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.view.LayoutInflater.rInflate(LayoutInflater.java:724)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.view.LayoutInflater.inflate(LayoutInflater.java:479)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.view.LayoutInflater.inflate(LayoutInflater.java:391)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.view.LayoutInflater.inflate(LayoutInflater.java:347)
04-16 18:10:24.573: E/AndroidRuntime(713):  at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:223)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.Activity.setContentView(Activity.java:1786)
04-16 18:10:24.573: E/AndroidRuntime(713):  at com.example.fragmentexample.SecondActivity.onCreate(SecondActivity.java:13)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.Activity.performCreate(Activity.java:4397)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1048)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1779)
04-16 18:10:24.573: E/AndroidRuntime(713):  ... 11 more
04-16 18:10:24.573: E/AndroidRuntime(713): Caused by: java.lang.NullPointerException
04-16 18:10:24.573: E/AndroidRuntime(713):  at com.example.fragmentexample.Fragment_2.onCreateView(Fragment_2.java:24)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:754)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:956)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.FragmentManagerImpl.addFragment(FragmentManager.java:1035)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.Activity.onCreateView(Activity.java:4177)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:664)
04-16 18:10:24.573: E/AndroidRuntime(713):  ... 21 more

How do I get the value from the bundle in SecondActivity.java to the Fragment_2.Java file?

Zoe
  • 27,060
  • 21
  • 118
  • 148
Vamsi Challa
  • 11,038
  • 31
  • 99
  • 149

18 Answers18

224

Step 1: To send data from a fragment to an activity

Intent intent = new Intent(getActivity().getBaseContext(),
                           TargetActivity.class);
intent.putExtra("message", message);
getActivity().startActivity(intent);

Step 2: To receive this data in an Activity:

Intent intent = getIntent();
String message = intent.getStringExtra("message");

Step 3: To send data from an activity to another activity, follow the normal approach

Intent intent = new Intent(MainActivity.this,
                           TargetActivity.class);
intent.putExtra("message", message);
startActivity(intent);

Step 4: To receive this data in an activity

  Intent intent = getIntent();
  String message = intent.getStringExtra("message");

Step 5.: From an Activity you can send data to a Fragment with the intent as:

Bundle bundle = new Bundle();
bundle.putString("message", "From Activity");

// Set Fragmentclass Arguments
Fragmentclass fragobj = new Fragmentclass();
fragobj.setArguments(bundle);

And to receive a fragment in the Fragment onCreateView method:

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

    return inflater.inflate(R.layout.fragment, container, false);
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Shiv
  • 4,569
  • 4
  • 25
  • 39
  • 2
    I tried step 5, That i'm calling listactivity from fragment and after selecting item from that activity, i want to come back in fragment with selected file name. But its not working, its giving me Nullpointer Exception at onCreateView. Any solution on this please? This is my question http://stackoverflow.com/questions/18208771/nullpointer-exception-while-returning-string-to-fragment-from-activity/18209614?noredirect=1#18209614 – OnkarDhane Aug 16 '13 at 09:59
  • how do I put a POJO here ? `bundle.putString("message", "From Activity"); ` – jeet.chanchawat Jan 12 '17 at 10:15
  • 57
    Is anyone disgusted at how convoluted doing something like this is – Ed Lee Feb 10 '17 at 06:48
  • 1
    Exactly Eddie, this is not the correct way. They should use interfaces to communicate between fragments via the container activity. – Kaveesh Kanwal Apr 08 '17 at 09:33
  • Regarding using interfaces to communicate between fragments: https://developer.android.com/training/basics/fragments/communicating.html – Andre L Torres Feb 21 '18 at 00:04
  • But, how to send data between fragments in ViewPager which belongs to Activity? A? – Nastromo May 11 '18 at 07:08
  • This does not work on button click. Everything on Stack is generic examples. Trying to take input from parent frag(inside main activity frame) send it to child frag(inside parent frag frame) and add it to the list on button click within parent frag. – wesley franks Jun 29 '19 at 20:31
  • I'ts best to use `String strtext=getArguments().getString("message");` on your `onCreate()` inside your fragment, since the view is not yet initialized , you can also do it in your `onCreateView()` as you do, but is cleaner and best practice to do it in `onCreate()` – Gastón Saillén Jul 10 '19 at 23:45
  • Better use activity than fragments. Implicit intent and explicit intent. So much easier – sophin Nov 20 '20 at 12:12
67

// In Fragment_1.java

Bundle bundle = new Bundle();
bundle.putString("key","abc"); // Put anything what you want

Fragment_2 fragment2 = new Fragment_2();
fragment2.setArguments(bundle);

getFragmentManager()
      .beginTransaction()
      .replace(R.id.content, fragment2)
      .commit();

// In Fragment_2.java

Bundle bundle = this.getArguments();

if(bundle != null){
     // handle your code here.
}

Hope this help you.

nguyencse
  • 1,028
  • 9
  • 17
55

As noted at developer site

Often you will want one Fragment to communicate with another, for example to change the content based on a user event. All Fragment-to-Fragment communication is done through the associated Activity. Two Fragments should never communicate directly.

communication between fragments should be done through the associated Activity.

Let's have the following components:

An activity hosts fragments and allow fragments communication

FragmentA first fragment which will send data

FragmentB second fragment which will receive datas from FragmentA

FragmentA's implementation is:

public class FragmentA extends Fragment 
{
    DataPassListener mCallback;
    
    public interface DataPassListener{
        public void passData(String data);
    }

    @Override
    public void onAttach(Context context) 
    {
        super.onAttach(context);
        // This makes sure that the host activity has implemented the callback interface
        // If not, it throws an exception
        try 
        {
            mCallback = (OnImageClickListener) context;
        }
        catch (ClassCastException e) 
        {
            throw new ClassCastException(context.toString()+ " must implement OnImageClickListener");
        }
    }
    
    public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) 
    {
        // Suppose that when a button clicked second FragmentB will be inflated
        // some data on FragmentA will pass FragmentB
        // Button passDataButton = (Button).........
        
        passDataButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (view.getId() == R.id.passDataButton) {
                    mCallback.passData("Text to pass FragmentB");
                }
            }
        });
    }
}

MainActivity implementation is:

public class MainActivity extends ActionBarActivity implements DataPassListener{
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        if (findViewById(R.id.container) != null) {
            if (savedInstanceState != null) {
                return;
            }
            getFragmentManager().beginTransaction()
                    .add(R.id.container, new FragmentA()).commit();
        }
    }
    
    @Override
    public void passData(String data) {
        FragmentB fragmentB = new FragmentB ();
        Bundle args = new Bundle();
        args.putString(FragmentB.DATA_RECEIVE, data);
        fragmentB .setArguments(args);
        getFragmentManager().beginTransaction()
            .replace(R.id.container, fragmentB )
            .commit();
    }
}

FragmentB implementation is:

public class FragmentB extends Fragment{
    final static String DATA_RECEIVE = "data_receive";
    TextView showReceivedData;
    
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_B, container, false);
        showReceivedData = (TextView) view.findViewById(R.id.showReceivedData);
    }
    
    @Override
    public void onStart() {
        super.onStart();
        Bundle args = getArguments();
        if (args != null) {
            showReceivedData.setText(args.getString(DATA_RECEIVE));
        }
    }
}

I hope this will help..

Community
  • 1
  • 1
ozhanli
  • 1,456
  • 18
  • 25
  • 5
    What is the OnImageClickListener here? and how is it cast to a DataPassListener variable? – Harsha Jul 03 '18 at 03:55
  • I found it's the "DataPassListener". I got it to work, but only to find due to every time the button is clicked the data is sent. When it is sent it replaces the fragment. Which means the list gets renewed every time. Therefore, not keeping the list of items in memory. – wesley franks Jun 29 '19 at 20:43
22

From the Developers website:

Often you will want one Fragment to communicate with another, for example to change the content based on a user event. All Fragment-to-Fragment communication is done through the associated Activity. Two Fragments should never communicate directly.

You can communicate among fragments with the help of its Activity. You can communicate among activity and fragment using this approach.

Please check this link also.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Jainendra
  • 24,713
  • 30
  • 122
  • 169
  • The second link that you have given, shows how to communicate between fragments when they are in the same activity. How do I communicate when both are in different activities? – Vamsi Challa Apr 16 '13 at 12:37
9

The latest solution for passing data between fragments can be implemented by using Android architectural components such as ViewModel and LiveData. With this solution, you don't need to define interface for communication and can get the advantages of using viewmodel like data survival due to configuration changes.

In this solution, the fragments involved in the communication share the same viewmodel object which is tied to their activity lifecycle. The view model object contains livedata object. One fragment sets data to be passed on livedata object and second fragment observers livedata changes and received the data.

Here is the complete example: Passing data between Android fragments using ViewModel

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Arnav Rao
  • 6,692
  • 2
  • 34
  • 31
6

First, all answers are right. You can pass the data except custom objects by using Intent.

If you want to pass the custom objects, you have to implement Serialazable or Parcelable to your custom object class. I thought it's too much complicated...

So if your project is simple, try to use DataCache. That provides a super simple way for passing data. Ref: GitHub project CachePot

1- Set this to View or Activity or Fragment which will send data

DataCache.getInstance().push(obj);

2- Get data anywhere like below

public class MainFragment extends Fragment
{
    private YourObject obj;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        obj = DataCache.getInstance().pop(YourObject.class);

    } //end onCreate()
} //end class MainFragment
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
kimkevin
  • 2,202
  • 1
  • 26
  • 48
  • Wouldn't it be easier to use an extra class with static values inside? These values can then be accessed by both fragments, so no need to use an extra library to cache custom objects. – Neph Mar 09 '20 at 12:36
6

Kotlin way

Use a SharedViewModel proposed at the official ViewModel documentation

It's very common that two or more fragments in an activity need to communicate with each other. Imagine a common case of master-detail fragments, where you have a fragment in which the user selects an item from a list and another fragment that displays the contents of the selected item. This case is never trivial as both fragments need to define some interface description, and the owner activity must bind the two together. In addition, both fragments must handle the scenario where the other fragment is not yet created or visible.

This common pain point can be addressed by using ViewModel objects. These fragments can share a ViewModel using their activity scope to handle this communication

First implement fragment-ktx to instantiate your viewmodel more easily

dependencies {
    implementation "androidx.fragment:fragment-ktx:1.2.2"
}

Then, you just need to put the data you will be sharing with the other fragment inside the viewmodel:

class SharedViewModel : ViewModel() {
    val selected = MutableLiveData<Item>()

    fun select(item: Item) {
        selected.value = item
    }
}

Then, to finish up, just instantiate your viewModel in each fragment, and set the value of selected from the fragment you want to set the data

Fragment A

class MasterFragment : Fragment() {

    private val model: SharedViewModel by activityViewModels()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        itemSelector.setOnClickListener { item ->
        model.select(item)
      }

    }
}

And then, just listen for this value at your Fragment destination

Fragment B

 class DetailFragment : Fragment() {

        private val model: SharedViewModel by activityViewModels()

        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)
            model.selected.observe(viewLifecycleOwner, Observer<Item> { item ->
                // Update the UI
            })
        }
    }

You can also do it in the opposite way

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Gastón Saillén
  • 12,319
  • 5
  • 67
  • 77
5

Specially now that Android team is pushing more towards adhering to single activity models, communication between the fragments becomes all the more important. LiveData and Interfaces are perfectly fine ways to tackle this issue. But now Google has finally addressed this problem and tried to bring a much simpler solution using FragmentManager. Here's how it can be done in Kotlin.

In the receiver fragment, add a listener:

setFragmentResultListener(
    "data_request_key",
    lifecycleOwner,
    FragmentResultListener { requestKey: String, bundle: Bundle ->
        // Unpack the bundle and use data
        val frag1Str = bundle.getString("frag1_data_key")

    })

In the sender fragment (frag1):

setFragmentResult(
    "data_request_key",
    bundleOf("frag1_data_key" to value)
)

Remember this functionality is only available in fragment-ktx version 1.3.0-alpha04 and up.

Credits and further reading:

A New Way to Pass Data Between Fragments

Android Fragments: Fragment Result

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Knight Forked
  • 1,529
  • 12
  • 14
4

Passing arguments between fragments. This is a fairly late to answer this question but it could help someone! Fragment_1.java

Bundle i = new Bundle(); 
            i.putString("name", "Emmanuel");

            Fragment_1 frag = new Fragment_1();
            frag.setArguments(i);
            FragmentManager fragmentManager = getFragmentManager();
            fragmentManager.beginTransaction()
                    .replace(R.id.content_frame
                            , new Fragment_2())
                    .commit();

Then in your Fragment_2.java you can get the paramaters normally within your onActivityCreated e.g

 Intent intent = getActivity().getIntent();
    if (intent.getExtras() != null) {
        String name =intent.getStringExtra("name");
    }
Emmanuel R
  • 65
  • 4
3

I think a good way to solve this problem is to use a custom interface.

Let’s say you have two fragments (A and B) which are inside of the same activity and you want to send data from A to B.

Interface:

public interface OnDataSentListener{
    void onDataSent(Object data);
}

Activity:

    public class MyActivity extends AppCompatActivity{

            private OnDataSentListener onDataSentListener;

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

                FragmentTransaction trans = getFragmentManager().beginTransaction();

                FragmentA fa = new FragmentA();
                FragmentB fb = new FragmentB();

               fa.setOnDataSentListener(new Listeners.OnDataSentListener() {
                    @Override
                    public void onDataSent(Object data) {
                         if(onDataSentListener != null)  onDataSentListener.onDataSent(data);
                    }
               });

                transaction.add(R.id.frame_a, fa);
                transaction.add(R.id.frame_b, fb);

                transaction.commit();
            }

            public void setOnDataSentListener(OnDataSentListener listener){
                this.onDataSentListener = listener;
            }
        }

Fragment A:

public class FragmentA extends Fragment{

    private OnDataSentListener onDataSentListener;

    private void sendDataToFragmentB(Object data){
        if(onDataSentListener != null) onDataSentListener.onDataSent(data);
    }

    public void setOnDataSentListener(OnDataSentListener listener){
        this.onDataSentListener = listener;
    }
}

Fragment B:

public class FragmentB extends Fragment{

    private void initReceiver(){
        ((MyActivity) getActivity()).setOnDataSentListener(new OnDataSentListener() {
            @Override
            public void onDataSent(Object data) {
                // Here you receive the data from fragment A
            }
        });
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
simpleApps
  • 754
  • 5
  • 5
2

Communicating between fragments is fairly complicated (I find the listeners concept a little challenging to implement).

It is common to use a 'Event Bus" to abstract these communications. This is a third-party library that takes care of this communication for you.

'Otto' is one that is used often to do this, and might be worth looking into: http://square.github.io/otto/

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Booger
  • 18,579
  • 7
  • 55
  • 72
2

Passing data from Fragment to another Fragment

  • From first Fragment

    // Set data to pass
    MyFragment fragment = new MyFragment(); //Your Fragment
    Bundle bundle = new Bundle();
    bundle.putInt("year", 2017)  // Key, value
    fragment.setArguments(bundle); 
    // Pass data to other Fragment
    getFragmentManager()
     .beginTransaction()
     .replace(R.id.content, fragment)
     .commit(); 
    
  • On Second Fragment

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
    
         Bundle bundle = this.getArguments();
         if (bundle != null) {
             Int receivedYear = bundle.getInt("year", ""); // Key, default value
         } 
    }
    
Martin Evans
  • 45,791
  • 17
  • 81
  • 97
Shujat Munawar
  • 1,657
  • 19
  • 23
1

This simple implementation helps to pass data between fragments in a simple way. Think you want to pass data from 'Frgment1' to 'Fragment2'

In Fragment1(Set data to send)

 Bundle bundle = new Bundle();
 bundle.putString("key","Jhon Doe"); // set your parameteres

 Fragment2 nextFragment = new Fragment2();
 nextFragment.setArguments(bundle);

 FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
 fragmentManager.beginTransaction().replace(R.id.content_drawer, nextFragment).commit();

In Fragment2 onCreateView method (Get parameteres)

String value = this.getArguments().getString("key");//get your parameters
Toast.makeText(getActivity(), value+" ", Toast.LENGTH_LONG).show();//show data in tost
Janaka
  • 398
  • 5
  • 16
  • In my app, I am trying to get this working but somehow though the value is being passed it is not being displayed on fragment2, I think I am making mistake in setting R.id.content_drawer. Can somebody guide me what could be the right identifier for R.id.content_drawer with .xml example. – falcon Apr 06 '19 at 09:10
1

You can achieve your goal by ViewModel and Live Data which is cleared by Arnav Rao. Now I put in an example to clear it more neatly.

First, the assumed ViewModel is named SharedViewModel.java.

public class SharedViewModel extends ViewModel {
    private final MutableLiveData<Item> selected = new MutableLiveData<Item>();

    public void select(Item item) {
        selected.setValue(item);
    }
    public LiveData<Item> getSelected() {
        return selected;
    }
}

Then the source fragment is the MasterFragment.java from where we want to send data.

public class MasterFragment extends Fragment {
    private SharedViewModel model;

    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        model = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
        itemSelector.setOnClickListener(item -> {

            // Data is sent

            model.select(item);
        });
    }
}

And finally the destination fragment is the DetailFragment.java to where we want to receive the data.

public class DetailFragment extends Fragment {

    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        SharedViewModel model = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
        model.getSelected().observe(getViewLifecycleOwner(), { item ->

           // Data is received

        });
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Gk Mohammad Emon
  • 6,084
  • 3
  • 42
  • 42
0

In your first fragment, put in this piece of code:

editprofile.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {

        Fragment_editprofile Fragment = new Fragment_editprofile();
            .
            .
            .
        Fragment.getintentdetails(tv_name.getText().toString(),
            tv_mob.getText().toString(), tv_email.getText().toString(), tv_dob.getText().toString(),
            tv_gender.getText().toString(), photointent);

    }
});

In the second fragment, make a method like below:

public void getintentdetails(String name, String mobile, String email, String dob,
                             String gender, String photointent) {

    this.name_str = name;
    this.mob_str = mobile;
    this.email_str = email;
    this.dob_str = dob;
    this.gender_str = gender;
    this.photo_str = photointent;
}

Then define a variable at the class level:

String name_str, mob_str, dob_str, photo_str, email_str, gender_str;

Then make another method in the second fragment to set a value:

setexistingdetails();

private void setexistingdetails() {

    if(!name_str.equalsIgnoreCase(""))
        (et_name).setText(name_str);
    if(!mob_str.equalsIgnoreCase(""))
        et_mobile.setText(mob_str);
    if(!email_str.equalsIgnoreCase(""))
        email_et.setText(email_str);
    if(!dob_str.equalsIgnoreCase(""))
        dob_et.setText(dob_str);
    if(!gender_str.equalsIgnoreCase("")) {
        if (gender_str.equalsIgnoreCase("m")){
            male_radio.setChecked(true);
        }
        else {
            female_radio.setChecked(true);
        }
    }
    if(!photo_str.equalsIgnoreCase("")) {
        try {
            Picasso.get().load(Const.BASE_PATH+"include/sub-domain/GENIUS/"+photo_str).into(adminpropic_edit);
        }
        catch (Exception e) {
        }
    }
}
Zoe
  • 27,060
  • 21
  • 118
  • 148
Adil Siddiqui
  • 287
  • 4
  • 14
0

You can use a couple of approaches to achieve the same:

  1. One would be to have an interface implemented in your parent activity so that fragment1 can pass information to its parent activity by calling those interface methods. Similarly you can have an interface implemented by fragment2 so that parent activity can send data to fragment2.

  2. Another simpler approach would be to call methods directly among each other. From fragment1 you can get its parent activity using framework APIs and then by defining your helper method in parent activity you can call that method directly from fragment1 and pass your information to the parent activity. Similarly in parent activity you can use framework APIs to get a reference to any of its child fragment, which say in your case is fragment2. Then you can define your own helper method in fragment2 so that you can call the same from parent activity and pass the information to fragment2.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
prateek
  • 440
  • 4
  • 12
-1

I’ve made something really easy for beginners like me. I made a textview in my activity_main.xml file and put in:

id = index
visibility = invisible

Then I get this textview from the first fragment:

index = (Textview) getActivity().findviewbyid(R.id.index)
index.setText("fill me with the value")

And then in the second fragment I get the value:

index = (Textview) getActivity().findviewbyid(R.id.index)
String get_the_value= index.getText().toString();
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
-1
Bundle bundle = new Bundle();
bundle.putString("mykey","abc"); 
bundle.putString("mykey2","abc"); // Put anything what you want

Fragment fragment = new Fragment();
fragment2.setArguments(bundle);

getFragmentManager()
  .beginTransaction()
  .replace(R.id.content, fragment2)
  .commit();

Bundle bundle = this.getArguments(); // in your fragment oncreate

if(bundle != null){
  String mykey = bundle.getString("mykey");
  String mykey2 = bundle.getString("mykey2");
  }
Mubashir Murtaza
  • 327
  • 2
  • 14