Créer une classe générale pour la boîte de dialogue personnalisée dans java Android
Mon application affiche de nombreuses boîtes de dialogue personnalisées comme Oui/Non ou Accepter/Annuler les décisions et, pendant que je codais, j'ai réalisé 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 le faire ou, plus exactement, la bonne façon de le faire(interfaces, classes abstraites, héritage, classes statiques, ...)
C'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 c'est 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 c'est améliorable, mais comment pourriez-vous faire cela?
Merci
6 answers
Créez d'abord une base DialogFragment
pour garder la main sur l'instance du Activity
. Ainsi, lorsque la boîte de dialogue est attachée au Activity
, vous connaîtrez l'instance du Activity
qui l'a créé.
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 un GeneralDialogFragment
qui étend le 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 mise en page personnalisée pour la boîte de dialogue,gonflez une mise en page 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;
}
Alors, Dans votre Activity
besoin de mettre en œuvre un 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, montrez le Dialog
de votre Activity
si nécessaire, comme ceci
GeneralDialogFragment generalDialogFragment =
GeneralDialogFragment.newInstance("title", "message");
generalDialogFragment.show(getSupportFragmentManager(),"dialog");
J'espère que cela aide. Je suis sûr que cette approche est l'une des méthodes optimisées, mais il pourrait y avoir aussi des approches différentes .
J'ai fait face à un problème comme vous. Et tout dans stackoverflow ne répond pas à ce que je veux. Je crée donc ma propre classe de dialogue et elle peut utiliser comme AlertDialog.Constructeur de la classe.
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 la forme de dialogue, je crée juste 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 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 d'alerte, tout simplement comme l'utilisation d'AlertDialog.Classe constructeur
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-ce que vous devriez appeler la fonction dismiss() dans votre OnClick. J'espère que cela peut vous aider. Et faites-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.
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:
Chemin d'appel
new CustomDialog().makeDialog(Activity.this,"pass value from diffrent-2 ");
Classe 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();
}
}
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);
}
}
J'utilise cela depuis un certain temps. Appel de la boîte de 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 l'ai récemment converti en kotlin. Appel de la boîte de dialogue d'alerte (dans 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 à afficher une boîte de dialogue de saisie de texte.