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:
- affiche un Fragment.
- si nécessaire, instanciez un DialogFragment.
- définissez le Fragment d'origine comme cible de ce DialogFragment, avec
.setTargetFragment()
. - afficher le DialogFragment avec .afficher () à partir du Fragment d'origine.
- 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 ().
- désactive le DialogFragment.
7 réponses
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.
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.
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.
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é
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. :)
public static void OpenDialog (Activity activity, DialogFragment fragment){
final FragmentManager fm = ((FragmentActivity)activity).getSupportFragmentManager();
fragment.show(fm, "tag");
}