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