¿Cómo pasar una variable de Activity a Fragment y pasarla de vuelta?

135

Actualmente estoy creando una aplicación para Android y quiero pasar una fecha entre la actividad y el fragmento. Mi actividad tiene un botón, que abre el fragmento: DatePickerFragment.

En mi actividad muestro una fecha, que quiero modificar con el fragmento. Entonces, quiero pasar la fecha al selector de fechas y enviarla nuevamente a la actividad.

He probado muchas soluciones, pero ninguna funciona. La manera fácil pasaría una discusión, pero esto no se puede hacer con fragmentos.

Eugene Primako
fuente
Mi problema es exactamente el mismo que el tuyo. Me pregunto por qué los ejemplos solo tratan los fragmentos en sí mismos como los "usuarios" del selector de fechas, no como la actividad que los inició.
Claudio

Respuestas:

213

Para pasar información a un fragmento , establezca Argumentos cuando lo cree, y puede recuperar este argumento más adelante en el método onCreate o onCreateView de su fragmento.

En la función newInstance de su fragmento, agrega los argumentos que desea enviarle:

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

Luego, dentro del fragmento del método onCreateo onCreateViewpuede recuperar los argumentos de esta manera:

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

Si ahora quiere comunicarse desde su fragmento con su actividad (enviando o no datos) , debe usar interfaces. La forma en que puede hacer esto se explica realmente bien en el tutorial de documentación de comunicación entre fragmentos. Debido a que todos los fragmentos se comunican entre sí a través de la actividad, en este tutorial puede ver cómo puede enviar datos desde el fragmento real a su contenedor de actividades para usar estos datos en la actividad o enviarlos a otro fragmento que contenga su actividad.

Tutorial de documentación:

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

jpardogo
fuente
10
Creo que el punto de las personas que hacen esta pregunta una y otra vez es que no está realmente bien explicado en la documentación.
Michael Alan Huff
1
Todavía estoy confundido sobre qué método es el mejor para usar, el suyo o el siguiente respondido por @Elenasys
Yoann Hercouet
Hay una nueva forma de compartir datos entre fragmentos utilizando componentes de arquitectura (E / S '17): developer.android.com/topic/libraries/architecture/…
jpardogo
¿Qué hay de esos fragmentos que se crean dentro del diseño XML?
ralphgabb
Ya no quiero usar el método estático.
Ahamadullah Saikat
89

Envío de datos desde ActivityaFragment

Actividad:

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

Fragmento:

Leer el valor en fragmento

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

Pero si desea enviar valores desde Fragment a Activity, lea la respuesta de jpardogo, debe necesitar interfaces, más información: Comunicación con otros Fragments

Jorgesys
fuente
2
¿Cómo pasar un objeto personalizado? Solía Parcelablepero eso me dioclass cast exception
viper
esta solución no me funciona, no puedo encontrar de dónde importar la transacción
thebeancounter
Bueno, si carga el Fragmento en su Actividad, puede enviar valores a través del paquete definido en su transacción. Explica cuál es tu escenario?
Jorgesys
8

gracias a @ ρяσѕρєя K y Terry ... me ayuda mucho y funciona perfectamente

Desde Actividad, envía datos con intención como:

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

y en el método Fragment onCreateView:

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

referencia: enviar datos de la actividad a fragmentos en Android

mahmoud zaher
fuente
7

Use la biblioteca EventBus para pasar el evento que podría contener su variable de un lado a otro. Es una buena solución porque mantiene sus actividades y fragmentos vagamente acoplados.

https://github.com/greenrobot/EventBus

SemáforoMetaphor
fuente
44
No puedo decir que esta no sea una buena solución, pero hay una palabra de precaución. Si bien EventBus es tremendamente fácil de usar, aquí también radica su peligro. Si comienza a agregar demasiadas señales, la naturaleza débilmente acoplada puede hacer que sea realmente difícil rastrear quién llama a quién y dónde tienen lugar diferentes eventos.
Johan Paul
2

Para todos los desarrolladores de Kotlin:

Aquí está la solución propuesta por Android Studio para enviar datos a su Fragmento (= cuando crea un Fragmento en blanco con archivo -> Nuevo -> Fragmento -> Fragmento (en blanco) y marca "incluir métodos de fábrica de fragmentos").

Pon esto en tu Fragmento:

class MyFragment: Fragment {

...

    companion object {

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

.applyes un buen truco para establecer datos cuando se crea un objeto, o como dicen aquí :

Llama a la función [bloque] especificada con el thisvalor como receptor y devuelve el thisvalor.

Luego, en su Actividad o Fragmento, haga lo siguiente:

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

y lea los Argumentos en su Fragmento como:

private var isMyBoolean = false

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

Para "enviar" datos a su Actividad , simplemente defina una función en su Actividad y haga lo siguiente en su Fragmento:

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

¡Disfruta de la magia de Kotlin!

Paul Spiesberger
fuente
1

Envío de datos de la actividad a fragmentos vinculados por XML

Si crea un fragmento en Android Studio utilizando una de las plantillas, por ejemplo, Archivo> Nuevo> Fragmento> Fragmento (Lista), el fragmento se vincula a través de XML. El método newInstance se crea en el fragmento pero nunca se llama, por lo que no se puede usar para pasar argumentos.

En cambio, en la Actividad, anule el método onAttachFragment

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

Luego lea los argumentos en el fragmento del método onCreate según las otras respuestas

Valle
fuente
0

Simplemente puede crear una instancia de su fragmento con un paquete:

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