web-dev-qa-db-fra.com

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

J'ai des fragments qui doivent montrer un dialogue régulier. Dans ces boîtes de dialogue, l'utilisateur peut choisir une réponse par oui ou par non, puis le fragment doit se comporter en conséquence.

Maintenant, la classe Fragment n'a pas de méthode onCreateDialog() à écraser, alors je suppose que je dois implémenter les dialogues à l'extérieur, dans le contenant Activity. C'est bon, mais alors Activity doit rendre compte de 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, de sorte que le fragment s’enregistre lui-même auprès de Activity avec une classe d’auditeur et que l’activité rende compte de la réponse, ou quelque chose du genre.

Mais cela semble être un énorme gâchis pour une tâche simple, comme afficher un "simple" dialogue de type oui-non dans un fragment. Aussi, de cette façon, mon Fragment serait moins autonome.

Y a-t-il une manière plus propre de faire ceci?

Edit:

La réponse à cette question n'explique pas vraiment en détail comment utiliser DialogFragments pour afficher les boîtes de dialogue à partir de fragments. Donc, autant que je sache, la voie à suivre est la suivante:

  1. Affichez un fragment.
  2. Si nécessaire, instanciez un DialogFragment.
  3. Définissez le fragment d'origine en tant que cible de ce DialogFragment, avec .setTargetFragment().
  4. Affichez le DialogFragment avec .show () à partir du fragment original.
  5. Lorsque l'utilisateur choisit une option sur ce DialogFragment, informe le fragment d'origine de cette sélection (par exemple, l'utilisateur a cliqué sur "oui"), vous pouvez obtenir la référence du fragment d'origine avec .getTarget ().
  6. Rejetez le DialogFragment.
114

Vous devez utiliser plutôt DialogFragment .

37
mgv

Je dois prudemment douter de la réponse précédemment acceptée selon laquelle l’utilisation d’un DialogFragment est la meilleure option. L'objectif principal (principal) de DialogFragment semble être d'afficher les fragments que sont dialogues eux-mêmes, et non d'afficher les fragments que ont doivent afficher.

Je crois que l'utilisation de l'activité du fragment pour faire la médiation entre le dialogue et le fragment est l'option préférable.

29
Mark D

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 le 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é

Si vous souhaitez implémenter le rappel, procédez comme suit 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 vous assurer que l’auditeur 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.
24
Warpzit

Pour moi, c'était la suivante-

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

Disposition 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 nom dialogfragment_heightfixhiddenbtn Le montre, je ne pouvais tout simplement pas trouver un moyen de remédier au fait que la hauteur du bouton du bas était réduite de moitié alors que wrap_content Était sélectionnée, et j'ai donc ajouté un bouton caché "en deux à la place. Désolé pour le hack.

12
EpicPandaForce
 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 custom

3
Alex Zaraos

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

Alors voici un lien externe qui m'a vraiment aidé à réaliser ce que je voulais. C'est très simple et facile à suivre aussi.

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

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

J'ai une activité principale qui héberge un fragment. Je voulais qu'une boîte de dialogue apparaisse au-dessus de la mise en page pour demander la saisie de l'utilisateur, puis traiter l'entrée en conséquence. Voir une capture d'écran

Voici à quoi ressemble 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 une confusion. :)

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

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

    fragment.show(fm, "tag");
}
0
Elmar Fazlagic