web-dev-qa-db-fra.com

Créer une classe générale pour un dialogue personnalisé en Java Android

Mon application affiche de nombreuses boîtes de dialogue personnalisées telles que Oui/Non ou Accepter/Annuler les décisions et, pendant que je codais, je me suis rendu compte qu'il y avait tellement de code répété, suivant le même schéma. 

Je veux construire une classe générale mais je ne sais pas comment faire ou plus exactement comment je dois le faire (interfaces, classes abstraites, héritage, classes statiques, ...)

Ceci est ma classe actuelle:

public class DialogTwoOptions extends Dialog {

TextView title_tv;
// Button yes_btn, no_btn;

public DialogTwoOptions(Context context) 
{
    super(context);     
    setContentView(R.layout.dialogo_sino); // a simple layout with a TextView and Two Buttons

    title_tv = (TextView) findViewById(R.id.dialogo_titulo_sino);
    // yes_btn = (Button) findViewById(R.id.dialogo_aceptar); 
    // no_btn = (Button) findViewById(R.id.dialogo_cancelar);

    View v = getWindow().getDecorView();
    v.setBackgroundResource(Android.R.color.transparent);
}

 public void quitDialog(View v) {
     if (isShowing()) dismiss();
 }

 public void setTitle(String title) {
     title_tv.setText(title);
 }

}

Et voici ce que je fais quand j'ai besoin d'utiliser cette classe:

final DialogTwoOptions dialog = new DialogTwoOptions(this);

    Button yes = (Button) dialog.findViewById(R.id.dialog_yes_btn);
    Button no = (Button) dialog.findViewById(R.id.dialog_no_btn);

    yes.setOnClickListener(new Button.OnClickListener() 
    {
        public void onClick(View v)     {
            dialog.dismiss();
            // Do something 
        }
    });

    no.setOnClickListener(new Button.OnClickListener() 
    {
        public void onClick(View v)     {
            dialog.dismiss();
            // Do something
        }
    });

    dialog.show();

Je suis sûr que cela peut être amélioré, mais comment pouvez-vous faire cela?

Merci

16
danigonlinea

Commencez par créer une base DialogFragment pour conserver l’instance de la Activity. Ainsi, lorsque la boîte de dialogue est attachée à Activity, vous connaîtrez l’instance de la Activity qui l’a créée.

public abstract class BaseDialogFragment<T> extends DialogFragment {
        private T mActivityInstance;

        public final T getActivityInstance() {
                return mActivityInstance;
        }

        @Override
        public void onAttach(Activity activity) {
                mActivityInstance = (T) activity;
            super.onAttach(activity);
        }

        @Override
        public void onDetach() {
                super.onDetach();
                mActivityInstance = null;
        }
}

Ensuite, créez une GeneralDialogFragment qui étend la BaseDialogFragment

public class GeneralDialogFragment extends BaseDialogFragment<GeneralDialogFragment.OnDialogFragmentClickListener> {

        // interface to handle the dialog click back to the Activity
        public interface OnDialogFragmentClickListener {
            public void onOkClicked(GeneralDialogFragment dialog);
            public void onCancelClicked(GeneralDialogFragment dialog);
        }

        // Create an instance of the Dialog with the input
        public static GeneralDialogFragment newInstance(String title, String message) {
            GeneralDialogFragment frag = new GeneralDialogFragment();
            Bundle args = new Bundle();
            args.putString("title", title);
            args.putString("msg", message);
            frag.setArguments(args);
            return frag;
        }
        // Create a Dialog using default AlertDialog builder , if not inflate custom view in onCreateView
        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {

            return new AlertDialog.Builder(getActivity())
                .setTitle(getArguments().getString("title"))
                .setMessage(getArguments().getString("message"))
                .setCancelable(false)
                .setPositiveButton("OK",
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int whichButton) {
                            // Positive button clicked
                            getActivityInstance().onOkClicked(GeneralDialogFragment.this);
                        }
                    }
                )
                .setNegativeButton("Cancel",
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int whichButton) {
                            // negative button clicked
                            getActivityInstance().onCancelClicked(GeneralDialogFragment.this);
                        }
                    }
                )
                .create();
        }

    }

Si vous devez utiliser votre propre disposition personnalisée pour la boîte de dialogue, gonflez une disposition dans onCreateView et supprimez onCreateDialog. Mais ajoutez les écouteurs de clic dans onCreateView comme je l'ai expliqué dans onCreateDialog 

 @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.activity_dialog, container, false);
    return view;
}

Ensuite, dans votre Activity besoin d'implémenter une interface pour gérer l'action dans dialog

public class TryMeActivity extends 
    FragmentActivity implements GeneralDialogFragment.OnDialogFragmentClickListener {

    @Override
        public void onOkClicked(GeneralDialogFragment dialog) {
                // do your stuff
        }

        @Override
        public void onCancelClicked(GeneralDialogFragment dialog) {
                // do your stuff
        }
}

Enfin, affichez la Dialog de votre Activity si nécessaire, comme ceci

    GeneralDialogFragment generalDialogFragment =
        GeneralDialogFragment.newInstance("title", "message");
    generalDialogFragment.show(getSupportFragmentManager(),"dialog");

J'espère que cela t'aides. Je suis sûr que cette approche est l’un des moyens optimaux, mais il pourrait aussi y avoir différentes approches. 

23
Libin

J'ai fait face à un problème comme toi. Et tout en stackoverflow ne répond pas à ce que je veux. Je crée donc ma propre classe de dialogue et elle peut être utilisée comme la classe AlertDialog.Builder.

Dans mon dialogxml.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:orientation="vertical"
    Android:background="@drawable/drconner">

    <LinearLayout
        Android:id="@+id/under"
        Android:orientation="vertical"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content">

    <TextView
        Android:id="@+id/malertTitle"
        Android:layout_width="match_parent"
        Android:layout_height="50dp"
        Android:padding="5dp"
        Android:textSize="25sp"
        Android:textColor="#ffffff"
        Android:drawablePadding="2dp"
        Android:background="@color/colorPrimaryDark"
        />

    <TextView
        Android:id="@+id/aleartMessage"
        Android:layout_width="match_parent"
        Android:layout_height="75dp"
        Android:padding="5dp"
        Android:textSize="18sp"
        Android:textColor="@color/colorAccent"/>
    </LinearLayout>

    <LinearLayout
        Android:layout_below="@+id/under"
        Android:layout_alignParentEnd="true"
        Android:layout_alignParentRight="true"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_marginBottom="1dp"
        Android:orientation="horizontal">

        <Button
            Android:id="@+id/aleartYes"
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            />

        <Button
            Android:id="@+id/aleartNo"
            Android:layout_marginLeft="30dp"
            Android:layout_marginStart="30dp"
            Android:layout_marginRight="3dp"
            Android:layout_marginEnd="3dp"
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content" />


    </LinearLayout>


</RelativeLayout>

Pour Dialog Shape, je crée simplement une forme simple xml - drconner.xml

<?xml version="1.0" encoding="utf-8"?>
<shape Android:shape="rectangle" xmlns:Android="http://schemas.Android.com/apk/res/Android">

    <corners Android:radius="5dp"/>
    <stroke Android:color="@color/colorPrimaryDark" Android:width="2dp"/>


</shape>

Pour créer une alerte personnalisée, je crée Alear.Java comme suit 

import Android.app.Dialog;
import Android.content.Context;
import Android.os.Bundle;
import Android.view.View;
import Android.view.Window;
import Android.widget.Button;
import Android.widget.TextView;



/**
 * Created by sanyatihan on 27-Dec-16.
 */

public class Alert extends Dialog {

    private String message;
    private String title;
    private String btYesText;
    private String btNoText;
    private int icon=0;
    private View.OnClickListener btYesListener=null;
    private View.OnClickListener btNoListener=null;

    public Alert(Context context) {
        super(context);
    }

    public Alert(Context context, int themeResId) {
        super(context, themeResId);
    }

    protected Alert(Context context, boolean cancelable, OnCancelListener cancelListener) {
        super(context, cancelable, cancelListener);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.dialogxml);
        TextView tv = (TextView) findViewById(R.id.malertTitle);
        tv.setCompoundDrawablesWithIntrinsicBounds(icon,0,0,0);
        tv.setText(getTitle());
        TextView tvmessage = (TextView) findViewById(R.id.aleartMessage);
        tvmessage.setText(getMessage());
        Button btYes = (Button) findViewById(R.id.aleartYes);
        Button btNo = (Button) findViewById(R.id.aleartNo);
        btYes.setText(btYesText);
        btNo.setText(btNoText);
        btYes.setOnClickListener(btYesListener);
        btNo.setOnClickListener(btNoListener);

    }



       public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public void setIcon(int icon) {
        this.icon = icon;
    }

    public int getIcon() {
        return icon;
    }

    public void setPositveButton(String yes, View.OnClickListener onClickListener) {
        dismiss();
        this.btYesText = yes;
        this.btYesListener = onClickListener;


    }

    public void setNegativeButton(String no, View.OnClickListener onClickListener) {
        dismiss();
        this.btNoText = no;
        this.btNoListener = onClickListener;


    }
}

Pour utiliser cette classe Alert, il suffit simplement d'utiliser la classe AlertDialog.Builder

par exemple :

final Alert mAlert = new Alert(this);
        mAlert.setTitle("This is Error Warning");
        mAlert.setIcon(Android.R.drawable.ic_dialog_alert);
        mAlert.setMessage("Do you want to delete?");
        mAlert.setPositveButton("Yes", new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mAlert.dismiss();
                //Do want you want
            }
        });

        mAlert.setNegativeButton("No", new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mAlert.dismiss();
                //Do want you want
            }
        });

        mAlert.show();

La chose principale est que vous devriez appeler la fonction de rejet () dans votre onClick. J'espère que cela peut vous aider. Et laissez-moi savoir si c'est ce que vous voulez ou non. Vous pouvez modifier la mise en page comme vous le souhaitez dans dialogxml.xml.

7
San Ko Ko

Je l'utilise depuis un certain temps . Appel du dialogue d'alerte dans une activité, où alertDialog est une fonction statique dans une classe appelée Misc:

    Misc.alertDlg(this, "Confirm", "Delete the file?", "Yes", null, "Cancel",
                    (DialogInterface dialog, int which) -> {
                        if(which == Misc.BTN_POS)
                            deleteYourFile()
                    });
}

Et la fonction de dialogue d'alerte (une fonction statique dans une classe appelée Misc:

static public void alertDlg(Context context, String title, String msg, String btnPos, String btnNeutral, String btnNeg, DialogInterface.OnClickListener ocListener) {
    Builder db = new AlertDialog.Builder(context);
    db.setTitle(title);
    db.setMessage(msg);
    if (btnPos != null) db.setPositiveButton(btnPos, ocListener);
    if (btnNeutral != null) db.setNeutralButton(btnNeutral, ocListener);
    if (btnNeg != null) db.setNegativeButton(btnNeg, ocListener);
    db.setIcon(Android.R.drawable.ic_dialog_alert);
    db.show();
}

Mais je viens de le convertir récemment en kotlin . Appel du dialogue d'alerte (en Kotlin):

    Misc.alertDlg(this, "Confirm", "Delete the file?", "Yes", null, "Cancel"){
        which-> if(which == Misc.BTN_POS) deleteYourFile()
    }

Et la fonction de dialogue d'alerte (une fonction dans un objet appelé Misc):

fun alertDlg(context: Context, title: String, msg: String, btnNeg: String?, btnNeutral: String?, btnPos: String?,
             onClickCallback: (which: Int) -> Unit) {
    val ocListener = DialogInterface.OnClickListener() {dialog, which ->
        onClickCallback(which)
    }
    val db = AlertDialog.Builder(context)
    db.setTitle(title)
    db.setMessage(msg)
    if (btnPos != null) db.setPositiveButton(btnPos, ocListener)
    if (btnNeutral != null) db.setNeutralButton(btnNeutral, ocListener)
    if (btnNeg != null) db.setNegativeButton(btnNeg, ocListener)
    db.setIcon(Android.R.drawable.ic_dialog_alert)
    db.show()
}

J'ai également utilisé une méthode similaire pour afficher un dialogue de saisie de texte.

0
Red wine
package com.example.jojo.gridview;
import Android.app.Dialog;
import Android.content.Context;
import Android.graphics.Bitmap;
import Android.os.Bundle;
import Android.view.Window;
import Android.widget.ImageView;
import Android.widget.TextView;
public class DialogClass extends Dialog {
 Bitmap b;
String n;
public DialogClass(Context context,Bitmap img,String name) {
    super(context);
    b=img;
    n=name;
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.dialog_style);
    ImageView image= (ImageView) findViewById(R.id.imageView2);
    TextView text= (TextView) findViewById(R.id.textView2);
    image.setImageBitmap(b);
    text.setText(n);

}

}

0
jojo

Vous pouvez utiliser AlertDialog et AlertDialog.Builder .

new AlertDialog.Builder(context)
    .setTitle("some_title")
    .setMessge("some_message")
    .setNegativeButton("No", null)
    .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(int which) {
                // do some action
            }
        })
    .show();
0
Karakuri

essayez le code ci-dessous:

voie d'appel

new CustomDialog().makeDialog(Activity.this,"pass value from diffrent-2 ");

class CustomDialog

public class CustomDialog
{

    public void makeDialog(Context con, String value)
    {
        final DialogTwoOptions dialog = new DialogTwoOptions(con);
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(R.layout.ur_xml);
        dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Android.graphics.Color.TRANSPARENT));
        // set the custom dialog components - text, image
        // and button
        dialog.setCanceledOnTouchOutside(false);
        Button yes = (Button) dialog.findViewById(R.id.dialog_yes_btn);
        Button no = (Button) dialog.findViewById(R.id.dialog_no_btn);

        yes.setOnClickListener(new Button.OnClickListener()
        {
            public void onClick(View v)
            {
                dialog.dismiss();
                // Do something
                if (value.equals("1"))
                {
                }
                else if (value.equals("1"))
                {
                }
                // do more condition
            }
        });

        no.setOnClickListener(new Button.OnClickListener()
        {
            public void onClick(View v)
            {
                dialog.dismiss();
                // Do something
                if (value.equals("1"))
                {
                }
                else if (value.equals("1"))
                {
                }
                // do more condition
            }
        });

        dialog.show();
    }
}
0
duggu