Cómo pasar valores entre fragmentos

109

Soy bastante nuevo en el uso de Fragmentos.

Solo estoy tratando de crear una aplicación de muestra simple que use Fragments. Mi escenario es que tengo dos actividades con un fragmento dentro de cada actividad. El primer fragmento tiene un texto de edición y un botón. El segundo fragmento tiene una vista de texto. Cuando ingreso un nombre en el texto de edición y hago clic en el botón, la vista de texto en el segundo fragmento debe mostrar el nombre ingresado en el texto de edición del primer fragmento.

Pude enviar el valor del primer fragmento a su actividad y luego de esa actividad a la segunda actividad. Ahora, ¿cómo uso este valor dentro del segundo fragmento?

Aquí está el código Java :::

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;


    }

}

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);
    }

}

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);
    }

}

Obtengo la siguiente excepción :::

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

¿Cómo obtengo el valor del paquete en SecondActivity.java al Fragment_2.Java?

Vamsi Challa
fuente
Resalte la parte en la que tiene el problema
Nikhil Agrawal
solución de trabajo con una manera fácil: stackoverflow.com/a/59332751/10201722
Adil Siddiqui

Respuestas:

203

paso 1. para enviar datos del fragmento a la actividad

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

paso 2. para recibir estos datos en la actividad:

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

paso 3 . para enviar datos de una actividad a otra actividad siga el enfoque normal

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

paso 4 para recibir estos datos en actividad

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

Paso 5. Desde Actividad, puede enviar datos a Fragment con la siguiente intención:

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

y para recibir en fragmento en el método Fragment onCreateView:

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

    return inflater.inflate(R.layout.fragment, container, false);
    }
Shiv
fuente
2
Probé el paso 5, que estoy llamando a listactivity desde el fragmento y después de seleccionar el elemento de esa actividad, quiero volver en el fragmento con el nombre de archivo seleccionado. Pero no está funcionando, me está dando Nullpointer Exception en onCreateView. ¿Alguna solución a esto por favor? Esta es mi pregunta stackoverflow.com/questions/18208771/…
OnkarDhane
¿Cómo pongo un POJO aquí? bundle.putString("message", "From Activity");
jeet.chanchawat
31
¿Alguien está disgustado por lo complicado que es hacer algo como esto?
Ed Lee
1
Exactamente Eddie, esta no es la forma correcta. Deben usar interfaces para comunicarse entre fragmentos a través de la actividad del contenedor.
Kaveesh Kanwal
Con respecto al uso de interfaces para comunicarse entre fragmentos: developer.android.com/training/basics/fragments/…
Andre L Torres
49

Como se indica en el sitio del desarrollador

A menudo, querrá que un fragmento se comunique con otro, por ejemplo, para cambiar el contenido en función de un evento de usuario. Toda la comunicación Fragmento a Fragmento se realiza a través de la Actividad asociada. Dos fragmentos nunca deben comunicarse directamente.

la comunicación entre fragmentos debe realizarse a través de la Actividad asociada.

Tengamos los siguientes componentes:

Una actividad aloja fragmentos y permite la comunicación de fragmentos.

Fragmento Un primer fragmento que enviará datos.

FragmentB segundo fragmento que recibirá datos de FragmentA

La implementación de FragmentA es:

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");
                }
            }
        });
    }
}

La implementación de MainActivity es:

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();
    }
}

La implementación de FragmentB es:

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));
        }
    }
}

Espero que esto sea de ayuda..

ozhanli
fuente
4
¿Qué es OnImageClickListener aquí? y ¿cómo se convierte en una variable DataPassListener?
Harsha
Encontré que es el "DataPassListener". Lo hice funcionar, pero solo para encontrarlo debido a que cada vez que se hace clic en el botón, se envían los datos. Cuando se envía, reemplaza el fragmento. Lo que significa que la lista se renueva cada vez. Por lo tanto, no guarda la lista de elementos en la memoria.
wesley franks
44

// En 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();

// En Fragment_2.java

Bundle bundle = this.getArguments();

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

Espero que esto te ayude.

nguyencse
fuente
1
Respuesta limpia para mostrar el punto principal. usar putString(o putInt) es la respuesta!
Mehdi Dehghani
22

Desde el sitio web de desarrolladores :

A menudo, querrá que un fragmento se comunique con otro, por ejemplo, para cambiar el contenido en función de un evento de usuario. Toda la comunicación Fragmento a Fragmento se realiza a través de la Actividad asociada. Dos fragmentos nunca deben comunicarse directamente.

Puede comunicarse entre fragmentos con la ayuda de su Actividad. Puede comunicarse entre actividad y fragmento utilizando este enfoque.

Consulte también este enlace.

Jainendra
fuente
El segundo enlace que ha proporcionado, muestra cómo comunicarse entre fragmentos cuando están en la misma actividad. ¿Cómo me comunico cuando ambos están en diferentes actividades?
Vamsi Challa
5

Primero, todas las respuestas son correctas, puede pasar los datos excepto los objetos personalizados usando Intent. Si desea pasar los objetos personalizados, usted tiene que poner en práctica Serialazableo Parcelablepara su clase de objeto personalizado. Pensé que era demasiado complicado ...

Entonces, si su proyecto es simple, intente usar DataCache. Eso proporciona una forma súper simple de pasar datos. Ref: Proyecto Github CachePot

1- Configure esto para Ver o Actividad o Fragmento que enviará datos

DataCache.getInstance().push(obj);

2- Obtenga datos en cualquier lugar como a continuación

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
Kimkevin
fuente
¿No sería más fácil usar una clase adicional con valores estáticos dentro? Ambos fragmentos pueden acceder a estos valores, por lo que no es necesario utilizar una biblioteca adicional para almacenar en caché los objetos personalizados.
Neph
4

La última solución para pasar datos entre fragmentos se puede implementar mediante el uso de componentes arquitectónicos de Android como ViewModel y LiveData. Con esta solución, no es necesario definir la interfaz para la comunicación y puede obtener las ventajas de usar viewmodel como la supervivencia de datos debido a cambios de configuración.

En esta solución, los fragmentos involucrados en la comunicación comparten el mismo objeto de modelo de vista que está vinculado a su ciclo de vida de actividad. El objeto de modelo de vista contiene un objeto de datos en vivo. Un fragmento establece los datos que se pasarán al objeto de datos en vivo y el segundo fragmento, los observadores de datos en vivo cambian y reciben los datos.

Aquí está el ejemplo completo http://www.zoftino.com/passing-data-between-android-fragments-using-viewmodel

Arnav Rao
fuente
3

Pasando argumentos entre fragmentos. Es bastante tarde para responder a esta pregunta, ¡pero podría ayudar a alguien! 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();

Luego, en su Fragment_2.java, puede obtener los parámetros normalmente dentro de su onActivityCreated eg

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

Creo que una buena forma de resolver este problema es utilizar una interfaz personalizada.

Supongamos que tiene dos fragmentos (A y B) que están dentro de la misma actividad y desea enviar datos de A a B.

Interfaz :

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

Actividad:

    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;
            }
        }

Fragmento 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;
    }
}

Fragmento 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
            }
        });
    }
}
simpleApps
fuente
2

La comunicación entre fragmentos es bastante complicada (encuentro que el concepto de oyentes es un poco difícil de implementar).

Es común utilizar un "Bus de eventos" para abstraer estas comunicaciones. Esta es una biblioteca de terceros que se encarga de esta comunicación por usted.

'Otto' es uno que se usa a menudo para hacer esto, y podría valer la pena investigarlo: http://square.github.io/otto/

Moco
fuente
2

Pasar datos de un fragmento a otro fragmento

  • Desde el primer fragmento

    // 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(); 
  • En el segundo fragmento

    @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
         } 
    }
Espíritu de solución
fuente
1

Esta sencilla implementación ayuda a pasar datos entre fragmentos de una forma sencilla. ¿Cree que desea pasar datos de 'Frgment1' a 'Fragment2'

En Fragment1 (Establecer datos para enviar)

 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();

En el método Fragment2 onCreateView (obtener parámetros)

String value = this.getArguments().getString("key");//get your parameters
Toast.makeText(getActivity(), value+" ", Toast.LENGTH_LONG).show();//show data in tost
Janaka
fuente
En mi aplicación, estoy tratando de que esto funcione, pero de alguna manera, aunque se está pasando el valor, no se muestra en fragment2, creo que estoy cometiendo un error al configurar R.id.content_drawer. ¿Alguien puede guiarme cuál podría ser el identificador correcto para R.id.content_drawer con el ejemplo .xml?
halcón
1

Camino de Kotlin

Utilice una SharedViewModelpropuesta en la documentación oficial de ViewModel

Es muy común que dos o más fragmentos de una actividad necesiten comunicarse entre sí. Imagine un caso común de fragmentos maestro-detalle, donde tiene un fragmento en el que el usuario selecciona un elemento de una lista y otro fragmento que muestra el contenido del elemento seleccionado. Este caso nunca es trivial ya que ambos fragmentos necesitan definir alguna descripción de interfaz, y la actividad del propietario debe unir los dos. Además, ambos fragmentos deben manejar el escenario donde el otro fragmento aún no se ha creado o no está visible.

Este problema común se puede abordar mediante el uso de objetos ViewModel. Estos fragmentos pueden compartir un ViewModel usando su alcance de actividad para manejar esta comunicación

Primero implemente fragment-ktx para instanciar su modelo de vista más fácilmente

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

Luego, solo necesita poner dentro del modelo de vista los datos que compartirá con el otro fragmento

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

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

Luego, para terminar, simplemente cree una instancia de su viewModel en cada fragmento y establezca el valor del selectedfragmento en el que desea configurar los datos

Fragmento 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)
      }

    }
}

Y luego, solo escuche este valor en su destino de Fragmento

Fragmento 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
            })
        }
    }

También puedes hacerlo al revés

Gastón Saillén
fuente
0

Solución de trabajo 100%: (si te ayuda, no olvides votar)

En su primer fragmento, coloque este fragmento de código:

    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);

                }
            });

En el segundo fragmento, haga un método como el siguiente:

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;

    }

luego defina una variable a nivel de clase:

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

luego haga otro método en el segundo fragmento para establecer el valor:

  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) {            }
        }
    }
Adil Siddiqui
fuente
0

Puede lograr su objetivo mediante ViewModel y Live Data, que Arnav Rao autoriza . Ahora pongo un ejemplo para aclararlo más nítidamente.

Primero, ViewModelse nombra el supuesto 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;
    }
}

Entonces, el fragmento de origen es MasterFragment.javadesde donde queremos enviar los datos.

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);
        });
    }
}

Y finalmente, el fragmento de destino es el lugar DetailFragment.javadonde queremos recibir los datos.

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 

        });
    }
}
Gk Mohammad Emon
fuente
0

De acuerdo, después de tanto investigar aquí, encontré una solución simple, en realidad nunca debe pasar los datos de un fragmento a otro, siempre es una mala idea, puede pasar los datos del fragmento A a la actividad y obtener los datos de la actividad en el fragmento B.

For Example
//fragment A
//your method that will be called in Main Activity for getting data from this fragment
public List<customDataModel> getlist(){
return mlist; //your custom list 
}
buttonopen.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //before calling  your new fragment, send a Broadcast signal to your main activity
 mContext.sendBroadcast(new Intent("call.myfragment.action"));
//here you are now changing the fragment
Fragment fragment1 = new VolunteerListDetailsFragment();

            FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
            ft.replace(R.id.content_frame, fragment1);
            ft.commit();
        }
    });

// en la actividad principal

this.registerReceiver(mBroadcastReceiver, new IntentFilter("call.myfragment.action"));//this line should be in your onCreate method
   BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {

    @Override
    public void onReceive(Context context, Intent intent) {
//init the fragment A
FragmenA fragment =
                (FragmentA) getSupportFragmentManager().findFragmentById(R.id.content_frame);
        mlistdetails = fragment.getlist();//this is my method in fragmentA which is retuning me a custom list, init this list type in top of on create fragment


    }
};
//here you are creating method that is returning the list that you just recieved From fragmentA
public List<customDataModel> getcustomlist(){
return mlistdetails; //you are returning the same list that you recived from fragmentA
}

// ahora en FragmentB

 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    View rootView = (View) inflater.inflate(R.layout.vol_listdetails, container, false);

    mlistdetails=((MainActivity)getActivity()).getcustomlist();//here you are calling the method that you have created in Main Activity

    Toast.makeText(getActivity().getApplicationContext(), mlistdetails.get(0).getItemqty(), Toast.LENGTH_SHORT).show();
    return rootView;

}
Mubashir Murtaza
fuente
-2

Hice algo realmente fácil para principiantes como yo ... hice una vista de texto en mi activity_main.xml y puse

id=index
visibility=invisible

luego obtengo esta vista de texto del primer fragmento

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

y luego en el segundo fragmento obtengo el valor

index= (Textview) getActivity().findviewbyid(R.id.index)
String get_the_value= index.getText().toString();

¡Espero eso ayude!

usuario7933515
fuente
La respuesta no está relacionada con la pregunta realizada
Kanagalingam