Domanda

Ho alcuni frammenti che devono mostrare una dialogo regolare. Su questi dialoghi l'utente può scegliere una risposta sì/no, e quindi il frammento dovrebbe comportarsi di conseguenza.

Ora il Fragment la classe non ha un onCreateDialog() metodo per sovrascrivere, quindi immagino di dover implementare le finestre di dialogo all'esterno, nel contenente Activity. Va bene, ma poi il Activity Deve riferire la risposta prescelta in qualche modo al frammento. Potrei ovviamente usare un modello di callback qui, quindi il frammento si registra al Activity Con una lezione di ascoltatore e l'attività riferirebbe la risposta attraverso quella, o qualcosa del genere.

Ma questo sembra essere un grosso disastro per un compito semplice come visualizzare un dialogo "semplice" sì in un frammento. Inoltre, in questo modo il mio Fragment sarebbe meno autonomo.

C'è qualche modo più pulito per farlo?

Modificare:

La risposta a questa domanda non spiega davvero in dettaglio come si dovrebbero usare i dialoghi per visualizzare i dialoghi dai frammenti. Quindi Afaik, la strada da percorrere è:

  1. Visualizza un frammento.
  2. Se necessario, istanziare un dialogo.
  3. Imposta il frammento originale come bersaglio di questo dialogo, con .setTargetFragment().
  4. Mostra il dialogo con .show () dal frammento originale.
  5. Quando l'utente sceglie un'opzione su questo dialogo, avvisare il frammento originale su questa selezione (ad esempio l'utente cliccato "Sì"), è possibile ottenere il riferimento del frammento originale con .GetTarget ().
  6. Respingere il dialogo.
È stato utile?

Soluzione

Dovresti usare un Dialogfragment invece.

Altri suggerimenti

Devo dubitare con cautela la risposta precedentemente accettata che l'uso di un dialogo è l'opzione migliore. Lo scopo (primario) previsto del dialogo sembra essere quello di mostrare frammenti sono Dialoge stesse, per non visualizzare frammenti avere Dialoghe da visualizzare.

Credo che usare l'attività del frammento per mediare tra la finestra di dialogo e il frammento sia l'opzione preferibile.

Ecco un esempio completo di un dialogo Sì/No:

La classe:

public class SomeDialog extends DialogFragment {

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        return new AlertDialog.Builder(getActivity())
            .setTitle("Title")
            .setMessage("Sure you wanna do this!")
            .setNegativeButton(android.R.string.no, new OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    // do nothing (will close dialog)
                }
            })
            .setPositiveButton(android.R.string.yes,  new OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    // do something
                }
            })
            .create();
    }
}

Per iniziare la finestra di dialogo:

        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        // Create and show the dialog.
        SomeDialog newFragment = new SomeDialog ();
        newFragment.show(ft, "dialog");

Potresti anche lasciare che la classe implementasse OnClickListener e usi che invece di ascoltatori incorporati.

Callback all'attività

Se vuoi implementare il callback, questo è come viene fatto nella tua attività:

YourActivity extends Activity implements OnFragmentClickListener

e

@Override
public void onFragmentClick(int action, Object object) {
    switch(action) {
        case SOME_ACTION:
        //Do your action here
        break;
    }
}

La classe di callback:

public interface OnFragmentClickListener {
    public void onFragmentClick(int action, Object object);
}

Quindi per eseguire un callback da un frammento devi assicurarti che l'ascoltatore sia allegato in questo modo:

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    try {
        mListener = (OnFragmentClickListener) activity;
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString() + " must implement listeners!");
    }
}

E un callback viene eseguito in questo modo:

mListener.onFragmentClick(SOME_ACTION, null); // null or some important object as second parameter.

Per me, era il seguente

Myfragment:

public class MyFragment extends Fragment implements MyDialog.Callback
{
    ShowDialog activity_showDialog;

    @Override
    public void onAttach(Activity activity)
    {
        super.onAttach(activity);
        try
        {
            activity_showDialog = (ShowDialog)activity;
        }
        catch(ClassCastException e)
        {
            Log.e(this.getClass().getSimpleName(), "ShowDialog interface needs to be     implemented by Activity.", e);
            throw e;
        }
    }

    @Override
    public void onClick(View view) 
    {
        ...
        MyDialog dialog = new MyDialog();
        dialog.setTargetFragment(this, 1); //request code
        activity_showDialog.showDialog(dialog);
        ...
    }

    @Override
    public void accept()
    {
        //accept
    }

    @Override
    public void decline()
    {
        //decline
    }

    @Override
    public void cancel()
    {
        //cancel
    }

}

Mydialog:

public class MyDialog extends DialogFragment implements View.OnClickListener
{
    private EditText mEditText;
    private Button acceptButton;
    private Button rejectButton;
    private Button cancelButton;

    public static interface Callback
    {
        public void accept();
        public void decline();
        public void cancel();
    }

    public MyDialog()
    {
        // Empty constructor required for DialogFragment
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        View view = inflater.inflate(R.layout.dialogfragment, container);
        acceptButton = (Button) view.findViewById(R.id.dialogfragment_acceptbtn);
        rejectButton = (Button) view.findViewById(R.id.dialogfragment_rejectbtn);
        cancelButton = (Button) view.findViewById(R.id.dialogfragment_cancelbtn);
        acceptButton.setOnClickListener(this);
        rejectButton.setOnClickListener(this);
        cancelButton.setOnClickListener(this);
        getDialog().setTitle(R.string.dialog_title);
        return view;
    }

    @Override
    public void onClick(View v)
    {
        Callback callback = null;
        try
        {
            callback = (Callback) getTargetFragment();
        }
        catch (ClassCastException e)
        {
            Log.e(this.getClass().getSimpleName(), "Callback of this class must be implemented by target fragment!", e);
            throw e;
        }

        if (callback != null)
        {
            if (v == acceptButton)
            {   
                callback.accept();
                this.dismiss();
            }
            else if (v == rejectButton)
            {
                callback.decline();
                this.dismiss();
            }
            else if (v == cancelButton)
            {
                callback.cancel();
                this.dismiss();
            }
        }
    }
}

Attività:

public class MyActivity extends ActionBarActivity implements ShowDialog
{
    ..

    @Override
    public void showDialog(DialogFragment dialogFragment)
    {
        FragmentManager fragmentManager = getSupportFragmentManager();
        dialogFragment.show(fragmentManager, "dialog");
    }
}

Dialogfragment Layout:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/dialogfragment_textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="10dp"
        android:text="@string/example"/>

    <Button
        android:id="@+id/dialogfragment_acceptbtn"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:layout_centerHorizontal="true"
        android:layout_below="@+id/dialogfragment_textview"
        android:text="@string/accept"
        />

    <Button
        android:id="@+id/dialogfragment_rejectbtn"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:layout_alignLeft="@+id/dialogfragment_acceptbtn"
        android:layout_below="@+id/dialogfragment_acceptbtn"
        android:text="@string/decline" />

     <Button
        android:id="@+id/dialogfragment_cancelbtn"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:layout_marginBottom="20dp"
        android:layout_alignLeft="@+id/dialogfragment_rejectbtn"
        android:layout_below="@+id/dialogfragment_rejectbtn"
        android:text="@string/cancel" />

     <Button
        android:id="@+id/dialogfragment_heightfixhiddenbtn"
        android:layout_width="200dp"
        android:layout_height="20dp"
        android:layout_marginTop="10dp"
        android:layout_marginBottom="20dp"
        android:layout_alignLeft="@+id/dialogfragment_cancelbtn"
        android:layout_below="@+id/dialogfragment_cancelbtn"
        android:background="@android:color/transparent"
        android:enabled="false"
        android:text=" " />
</RelativeLayout>

Come il nome dialogfragment_heightfixhiddenbtn mostra che non sono riuscito a trovare un modo per risolvere che l'altezza del pulsante in basso è stata tagliata a metà nonostante dicesse wrap_content, quindi ho aggiunto un pulsante nascosto per essere invece "tagliato" a metà. Ci scusiamo per l'hack.

 public void showAlert(){


     AlertDialog.Builder alertDialog = new AlertDialog.Builder(getActivity());
     LayoutInflater inflater = getActivity().getLayoutInflater();
     View alertDialogView = inflater.inflate(R.layout.test_dialog, null);
     alertDialog.setView(alertDialogView);

     TextView textDialog = (TextView) alertDialogView.findViewById(R.id.text_testDialogMsg);
     textDialog.setText(questionMissing);

     alertDialog.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
         public void onClick(DialogInterface dialog, int which) {
             dialog.cancel();
         }
     });
     alertDialog.show();

}

dove .test_dialog è di XML personalizzato

Anch'io sono un principiante e onestamente non sono riuscito a trovare una risposta soddisfacente che potrei capire o implementare.

Quindi ecco un link esterno che mi sono davvero aiutato a raggiungere ciò che volevo. È anche molto semplice e facile da seguire.

http://www.helloandroid.com/tutorials/how-display-custom-dialog-your-android-application

Questo è quello che ho cercato di ottenere con il codice:

Ho una mainttività che ospita un frammento. Volevo che venga visualizzato una finestra di dialogo in cima al layout per chiedere l'input dell'utente e quindi elaborare l'input di conseguenza.Vedi uno screenshot

Ecco come è l'OncreateView del mio frammento

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

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

    Button addTransactionBtn = rootView.findViewById(R.id.addTransactionBtn);

    addTransactionBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Dialog dialog = new Dialog(getActivity());
            dialog.setContentView(R.layout.dialog_trans);
            dialog.setTitle("Add an Expense");
            dialog.setCancelable(true);

            dialog.show();

        }
    });

Spero che ti aiuti

Fammi sapere se c'è qualche confusione. :)

    public static void OpenDialog (Activity activity, DialogFragment fragment){

    final FragmentManager fm = ((FragmentActivity)activity).getSupportFragmentManager();

    fragment.show(fm, "tag");
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top