DialogFragment – Come restituire valori all’Activity dopo onDismiss

Ho effettuato numerose ricerche per tentare di far restituire determinati valori che vengono elaborati in un DialogFragment all’activity che lo chiama e finalmente ho trovato una soluzione molto elegante che mi piacerebbe condividere con voi.

Nel mio caso specifico, ho una ListView con una serie di item e, al tocco di uno di essi, si apre il famoso DialogFragment per poterne modificare alcuni valori (nome e descrizione). La soluzione è molto semplice e sfrutta un’interfaccia ma vediamo subito il codice per capire di cosa stiamo parlando.

Creazione dell’interfaccia

Innanzitutto bisogna creare una piccola classe (un’interfaccia appunto) che contiene la dichiarazione del metodo che utilizzeremo nell’Activity per modificare i valori dell’item presente nell’Adapter. Sono pochissime righe di codice ma fondamentali purchè tutto funzioni:

package com.test.interfaces;

public interface DialogDismiss
{
    public void handleDialogClose(String s_nome, String s_descrizione);
}

Come potete notare dal package, ne ho creato uno che andrà ad ospitare le varie interfacce ma non è fondamentale e potete crearla dove volete. Ho dichiarato che il metodo handleDialogClose() prende in input due parametri che, in questo caso, sono fondamentali al mio progetto ma potete passarne quanti volete e del tipo che volete.

Creazione del DialogFragment

Ho l’abitudine di essere molto metodico ed ordinato quindi quasi tutti i dialogs che mi servono li inserisco in un package specifico. Eccone un estratto

public class CustomDialog extends DialogFragment{

	public Button save_btn,back_btn;

	public int _id = 0;
	public String s_nome="";
	public String s_description="";


	public CustomDialog(){
		this.setCancelable(false);

	}

	/**
	 * CALLBACK PER GESTIRE LA CHIUSURA
	 * @param dialog
	 */
	public void onDismiss(DialogInterface dialog)
	{
		Activity activity = getActivity();
		if(activity instanceof DialogDismiss)
			((DialogDismiss)activity).handleDialogClose(s_nome,s_description);
	}

	public static CustomDialog newInstance(String _nome,String _descrizione, int _id){
		CustomDialog frag = new CustomDialog();
		Bundle args = new Bundle();
		args.putInt("id", _id);
		args.putString("nome", _nome);
		args.putString("descrizione", _descrizione);
		frag.setArguments(args);
		return frag;
	}

	@Override
	public Dialog onCreateDialog(Bundle savedInstanceState) {

		this._id = getArguments().getInt("id");
		this.s_nome = getArguments().getString("nome");
		this.s_description = getArguments().getString("descrizione");
		/*
		OPERAZIONI NECESSARIE
		salvataggi su server
		task asincroni etc...

		*/
		LayoutInflater inflater = getActivity().getLayoutInflater();
		View view = inflater.inflate(R.layout.MIOLAYOUT, null);
		final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
		builder.setView(view);
		builder.setCustomTitle(null);
		/**
		 * LISTNER BOTTONI
		 */
		return builder.create();
	}

}

Il metodo che ci interessa è onDismiss al cui interno è presente la chiamata alla callback che restituirà all’Activity chiamante ciò che voi inserirete come parametri. Attenzione, se si aggiunge o rimuove un parametro all’interno della classe CustomDialog è obbligatorio modificare la dichiarazione del metodo dell’interfaccia DialogDismiss.

Activity e ritorno dei valori

Finalmente vediamo come l’Activity sarà in grado di ricevere i dati di ritorno dal DialogFragment appena creato. Il primo passo da fare è far implementare all’activity l’interfaccia DialogDismiss come segue

public class TestActivity extends Activity implements DialogDismiss { .....

Ora siete in grado di fornire un’implementazione al metodo dichiarato nell’interfaccia ( handleDialogClose() ), la mia implementazione recupera l’elemento interessato dall’adapter e ne imposto i nuovi valori. Ecco il codice

/**
     * Mostra il dialog CustomDialog ed imposta il segnaposto editing_position
     * @param n_nome
     * @param n_descrizione
     * @param id
     * @param position
     */
public void showEditDialog(String nome, String descrizione, int id, int position){
        editing_position=position; //DICHIARATA COME ATTRIBUTO DELLA CLASSE public/private
        CustomDialog dia=CustomDialog.newInstance(nome,descrizione,id);
        dia.show(getFragmentManager(), "MIOTAG");
    }


/**
     * CallBack per gestire il ritorno dall'alert dialog
     * @param n_nome
     * @param n_descrizione
     */
    @Override
    public void handleDialogClose(String n_nome, String n_descrizione) {
        data_list.get(editing_position).setDescrizione(n_descrizione);
        data_list.get(editing_position).setNome(n_nome);
        mAdapter.notifyDataSetChanged();
        
    }

Il metodo showEditDialog(..) deve essere invocato quando si tocca un elemento della ListView, potete modificare i parametri impostando ciò di cui il vostro CustomDialog ha bisogno.
La variabile mAdapter altro non è che l’adapter assegnato alla ListView mentre data_list sono i valori passati all’adapter. Dopo aver imostato i nuovi valori all’ArrayList data_list è necessario invocare il metodo notifyDataSetChanged() affinchè a video compaiano le modifiche.

La variabile editing_position è una sorta di segnaposto che imposto al tocco dell’elemento della listview in modo da poter recuperare l’item corretto. Questo è quanto!

Non sò se questo approccio sia la soluzione più corretta ma sicuramente è molto scalabile e funzionale. Se avete problemi oppure non capite qualcosa nell’articolo postate pure il vostro commento!

 

TizianoZullo.it

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *


*