Afficher la boîte de dialogue à partir du fragment?

J'ai quelques fragments qui doivent montrer une boîte de dialogue régulière. Sur ces boîtes de dialogue, l'utilisateur peut choisir une réponse oui/non, puis le fragment doit se comporter en conséquence.

Maintenant, la classe Fragment n'a pas de méthode onCreateDialog() à remplacer, donc je suppose que je dois implémenter les boîtes de dialogue à l'extérieur, dans le Activity contenant. C'est ok, mais alors le Activity doit rapporter la réponse choisie d'une manière ou d'une autre au fragment. Je pourrais bien sûr utiliser un modèle de rappel ici, donc le fragment s'enregistre à le Activity avec une classe d'écoute, et l'activité rapporterait la réponse à travers cela, ou quelque chose comme ça.

Mais cela semble être un gros gâchis pour une tâche simple comme l'affichage d'une boîte de dialogue" simple " oui-non dans un fragment. Aussi, de cette façon mon Fragment serait moins autonome.

Y a-t-il un moyen plus propre de le faire?

Modifier:

La réponse à cette question n'explique pas vraiment en détail comment utiliser DialogFragments pour afficher les dialogues de Fragment. Alors AFAIK, le chemin à parcourir est:

  1. affiche un Fragment.
  2. si nécessaire, instanciez un DialogFragment.
  3. définissez le Fragment d'origine comme cible de ce DialogFragment, avec .setTargetFragment().
  4. afficher le DialogFragment avec .afficher () à partir du Fragment d'origine.
  5. lorsque l'utilisateur choisit une option sur ce DialogFragment, avertissez le Fragment original de cette sélection (par exemple, l'Utilisateur a cliqué sur "Oui"), vous pouvez obtenir la référence de l'original Fragment avec .getTarget ().
  6. désactive le DialogFragment.
113
demandé sur Shubham Soni 2011-03-22 17:58:39

7 réponses

Vous devriez utiliser un DialogFragment à la place.

37
répondu mgv 2011-03-23 01:25:18

Je dois douter prudemment de la réponse précédemment acceptée selon laquelle l'utilisation d'un DialogFragment est la meilleure option. Le but (principal) du DialogFragment semble être d'Afficher des fragments qui sont des boîtes de dialogue elles-mêmes, pas d'Afficher des fragments qui ont des boîtes de dialogue à afficher.

Je crois que l'utilisation de l'activité du fragment pour servir de médiateur entre la boîte de dialogue et le fragment est l'option préférable.

28
répondu Mark D 2011-03-28 17:52:07

Voici un exemple complet d'un DialogFragment oui/non:

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

Pour démarrer la boîte de dialogue:

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

Vous pouvez également laisser la classe implémenter onClickListener et l'utiliser à la place des écouteurs intégrés.

Rappel à l'Activité de

Si vous voulez implémenter le rappel, voici comment cela se fait Dans votre activité:

YourActivity extends Activity implements OnFragmentClickListener

Et

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

La classe de rappel:

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

Ensuite, pour effectuer un rappel à partir d'un fragment, vous devez assurez-vous que l'écouteur est attaché comme ceci:

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

Et un rappel est effectué comme ceci:

mListener.onFragmentClick(SOME_ACTION, null); // null or some important object as second parameter.
22
répondu Warpzit 2014-02-03 06:40:39

Pour moi, c'était ce qui suit -

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

Activité:

public class MyActivity extends ActionBarActivity implements ShowDialog
{
    ..

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

Mise en page DialogFragment:

<?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>

Comme le montre le nom dialogfragment_heightfixhiddenbtn, Je ne pouvais tout simplement pas trouver un moyen de réparer que la hauteur du bouton du bas était coupée en deux malgré le fait que wrap_content ait été dit, alors j'ai ajouté un bouton caché pour être "coupé" en deux à la place. Désolé pour le hack.

10
répondu EpicPandaForce 2014-09-15 09:59:56
 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();

}

Où .test_dialog est de xml personnalisé

3
répondu Alex Zaraos 2015-05-08 22:40:33

Je suis moi-même un débutant et honnêtement, je n'ai pas pu trouver une réponse satisfaisante que je pouvais comprendre ou mettre en œuvre.

Voici donc un lien externe que je m'ai vraiment aidé à réaliser ce que je voulais. C'est très simple et facile à suivre.

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

CE QUE J'AI ESSAYÉ DE RÉALISER AVEC LE CODE:

J'ai une MainActivity qui héberge un Fragment. Je voulais un boîte de dialogue à apparaître sur le dessus de la mise en page pour demander l'entrée de l'utilisateur, puis traiter l'entrée en conséquence. Voir une capture d'écran

Voici à quoi ressemble le onCreateView de mon fragment

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

        }
    });

J'espère que cela vous aidera

Faites-moi savoir s'il y a confusion. :)

1
répondu Junaid Aziz 2017-10-22 12:54:15
    public static void OpenDialog (Activity activity, DialogFragment fragment){

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

    fragment.show(fm, "tag");
}
0
répondu Elmar Fazlagic 2017-09-06 06:58:55