Come passare una variabile dall'attività al frammento e passarla indietro?


135

Attualmente sto realizzando un'app Android e voglio passare una data tra attività e frammento. La mia attività ha un pulsante che apre il frammento: DatePickerFragment.

Nella mia attività mostro una data, che voglio modificare con il frammento. Quindi voglio passare la data al datepicker e rispedirla all'attività.

Ho provato molte soluzioni, ma nessuna funziona. Il modo semplice sarebbe passare un argomento, ma questo non può essere fatto con i frammenti.


Il mio problema è esattamente uguale al tuo. Mi chiedo perché gli esempi trattino solo i frammenti stessi come "utenti" del selettore di date, non l'attività che li ha avviati.
Claudio

Risposte:


213

Per passare le informazioni a un frammento , impostaArguments quando lo crei e puoi recuperare questo argomento in un secondo momento con il metodo onCreate o onCreateView del tuo frammento.

Sulla funzione newInstance del tuo frammento aggiungi gli argomenti che vuoi inviargli:

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

Quindi all'interno del frammento del metodo onCreateo onCreateViewè possibile recuperare gli argomenti in questo modo:

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

Se vuoi ora comunica dal tuo frammento con la tua attività (invio o meno di dati) , devi utilizzare le interfacce. Il modo in cui puoi farlo è spiegato molto bene nel tutorial di documentazione sulla comunicazione tra frammenti. Poiché tutti i frammenti comunicano tra loro attraverso l'attività, in questa esercitazione è possibile vedere come è possibile inviare i dati dal frammento effettivo al suo contenitore di attività per utilizzare questi dati sull'attività o inviarli a un altro frammento che contiene l'attività.

Tutorial sulla documentazione:

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


10
Penso che il punto in cui le persone pongono questa domanda ancora e ancora sia che non sia davvero ben spiegato nella documentazione.
Michael Alan Huff,

1
Sono ancora confuso su quale sia il metodo migliore da usare, il tuo o quello sotto indicato da @Elenasys
Yoann Hercouet,

Esiste un nuovo modo di condividere i dati tra i frammenti utilizzando i componenti dell'architettura (I / O '17): developer.android.com/topic/libraries/architecture/…
jpardogo,

Che ne dici di quei frammenti che vengono creati all'interno del layout XML?
ralphgabb,

Non voglio più usare il metodo statico.
Ahamadullah Saikat,

89

Invio di dati da ActivityaFragment

Attività:

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

Frammento:

Lettura del valore in frammento

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

Ma se vuoi inviare valori da Frammento ad Attività, leggi la risposta di jpardogo, devi avere bisogno di interfacce, maggiori informazioni: Comunicare con altri Frammenti


2
Come passare un oggetto personalizzato? Ho usato Parcelablema questo mi ha datoclass cast exception
vipera il

questa soluzione non funziona per me, non riesco a trovare da dove importare la transazione
thebeancounter

Bene, se carichi il frammento nella tua attività, puoi inviare valori tramite bundle definito nella tua transazione. Spiega qual è il tuo scenario?
Jorgesys,

8

grazie a @ ρяσѕρєя K e Terry ... mi aiuta molto e funziona perfettamente

Dall'attività si inviano i dati con l'intento di:

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

e nel metodo 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);
}

riferimento: invia i dati dall'attività al frammento in Android


7

Utilizzare la libreria EventBus per passare l'evento che potrebbe contenere la variabile avanti e indietro. È una buona soluzione perché mantiene le attività e i frammenti liberamente accoppiati

https://github.com/greenrobot/EventBus


4
Non posso dire che questa non sia una buona soluzione, ma è presente un avvertimento. Mentre EventBus è incredibilmente facile da usare, qui sta anche il suo pericolo. Se inizi ad aggiungere troppi segnali, la natura vagamente accoppiata può rendere davvero difficile tenere traccia di chi chiama chi e dove avvengono eventi diversi.
Johan Paul,

2

Per tutti gli sviluppatori di Kotlin là fuori:

Ecco la soluzione proposta da Android Studio per inviare dati al tuo frammento (= quando crei un frammento vuoto con File -> Nuovo -> Frammento -> Frammento (vuoto) e controlli "includi metodi di fabbrica frammento").

Metti questo nel tuo frammento:

class MyFragment: Fragment {

...

    companion object {

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

.applyè un bel trucco per impostare i dati quando viene creato un oggetto o come indicato qui :

Chiama la funzione specificata [blocco] con thisvalore come ricevitore e restituisce thisvalore.

Quindi nella tua attività o frammento fai:

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

e leggi gli Argomenti nel tuo frammento come:

private var isMyBoolean = false

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

Per "inviare" i dati alla tua attività , definisci semplicemente una funzione nella tua attività e procedi come segue nel tuo frammento:

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

Goditi la magia di Kotlin!


1

Invio di dati da attività a frammenti collegati da XML

Se crei un frammento in Android Studio utilizzando uno dei modelli, ad esempio File> Nuovo> Frammento> Frammento (Elenco), il frammento è collegato tramite XML. Il metodo newInstance viene creato nel frammento ma non viene mai chiamato, quindi non può essere utilizzato per passare argomenti.

Invece nell'attività sovrascrivere il metodo onAttachFragment

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

Quindi leggi gli argomenti nel frammento del metodo onCreate secondo le altre risposte


0

Puoi semplicemente creare un'istanza del tuo frammento con un pacchetto:

Fragment fragment = Fragment.instantiate(this, RolesTeamsListFragment.class.getName(), bundle);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.