DialogFragment listener is null after rotation

23 Views Asked by At

I have a Fragment that creates a DialogFragment. When user taps on the positive button or cancel/dismissed the dialog, I do something. To achieve that, I have a listener. The problem I have is that if user opens the dialog, and then rotates the screen, when the user taps on the positive button or cancel/dismissed the dialog, the app crashes because the listener is null.

I have tried to fix this following this solution: https://stackoverflow.com/a/14044934/21021740

However, the call to .findFragmentByTag() is always null and I don't know why.

My Fragment:

public class ListaFragment extends BaseTemporadaFragment {
    private FiltroFragment.FiltroListener filtroListener;
    private FiltroFragment dialogFragment;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        this.filtroListener = new FiltroFragment.FiltroListener() {
            @Override
            public void onDialogPositiveClick(DialogFragment dialog) {
                applyFilter();
            }

            @Override
            public void OnCancelListener(DialogFragment dialog) {
                cancelChanges();
            }
        };
        
        if (savedInstanceState == null) {
            this.dialogFragment = new FiltroFragment();
            this.dialogFragment.setListener(this.filtroListener);
        } else {
            this.dialogFragment = (FiltroFragment) MainActivity.fragmentManager
                    .findFragmentByTag(FiltroFragment.TAG);
            if (this.dialogFragment != null) {
                this.dialogFragment.setListener(this.filtroListener);
            }
        }
    }

    // TODO
    @Override
    public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
        inflater.inflate(R.menu.filtro, menu);
        super.onCreateOptionsMenu(menu, inflater);
    }

    // TODO
    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        if (item.getItemId() == R.id.menu_filtro) {
            this.dialogFragment.show(MainActivity.fragmentManager, FiltroFragment.TAG);
        }
        return super.onOptionsItemSelected(item);
    }
}

My DialogFragment:

public class FiltroFragment extends DialogFragment {

    public interface FiltroListener {
        public void onDialogPositiveClick(DialogFragment dialog);
        public void OnCancelListener(DialogFragment dialog);
    }

    private FiltroListener listener;
    public static final String[] TIPOS = new String[]{"Liga", "Copa", "Amistosos"};
    private boolean[] seleccion = new boolean[]{true, true, true};

    @NonNull
    @Override
    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
        AlertDialog.Builder builder = new AlertDialog.Builder(this.getActivity());
        builder.setTitle(this.getResources().getString(R.string.titulo));
        builder.setMultiChoiceItems(FiltroFragment.TIPOS, this.seleccion,
                new DialogInterface.OnMultiChoiceClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i, boolean b) {
                        //cambiarSeleccion(i, b);
                    }
                });
        builder.setPositiveButton(R.string.aplicar, 
                new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                listener.onDialogPositiveClick(FiltroFragment.this);
        });
        return builder.create();
    }

    @Override
    public void onCancel(@NonNull DialogInterface dialog) {
        super.onCancel(dialog);
        listener.OnCancelListener(FiltroFragment.this);
    }

    public boolean[] getSeleccion() {
        return this.seleccion;
    }

    public void setSeleccion(boolean[] seleccion) {
        this.seleccion = seleccion;
    }

    public void setListener(FiltroListener listener) {
        this.listener = listener;
    }
}

UPDATE:

It works if I add below code to my DialogFragment, but I do not know if that is an appropiate solution because it seems setRetainInstance() is deprecated:

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setRetainInstance(true);
}
0

There are 0 best solutions below