在java Android中为自定义Dialog创建一个通用类

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23408756/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 22:52:10  来源:igfitidea点击:

Create a general class for custom Dialog in java Android

javaandroidgenericsdialog

提问by danigonlinea

My app shows many custom dialog like Yes/No or Accept/Cancel decissions and, while I was coding, I realized that there are so much code repeated, following the same schema.

我的应用程序显示了许多自定义对话框,如是/否或接受/取消决策,在我编码时,我意识到有很多代码重复,遵循相同的模式。

I want to build a general class but I don't know how to do it or, more exactly, the correct way that I have to do it(interfaces, abstract classes, inheritance, static classes, ...)

我想构建一个通用类,但我不知道该怎么做,或者更确切地说,我必须做的正确方法(接口、抽象类、继承、静态类……)

This is my current class:

这是我目前的课程:

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

}

}

And this is what I am doing when I need to use this class:

当我需要使用这个类时,这就是我正在做的事情:

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

I am sure that it is improvable, but how could you do this?

我确信它是可以改进的,但你怎么能做到这一点?

Thanks

谢谢

采纳答案by Libin

First create an Base DialogFragmentto keep hold of the instance of the Activity. So when the Dialog is attached to the Activity, you will know the instance of the Activitywhich created it.

首先创建一个 BaseDialogFragment来保持Activity. 因此,当 Dialog 附加到 时Activity,您将知道Activity创建它的 实例。

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

Then, create a GeneralDialogFragmentwhich extends the BaseDialogFragment

然后,创建一个GeneralDialogFragment扩展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();
        }

    }

If you need to use your own custom layout for dialog,then inflate a layout in onCreateViewand remove onCreateDialog. But Add the click listeners in onCreateViewlike i explained in onCreateDialog

如果您需要为对话框使用自己的自定义布局,则在布局中膨胀onCreateView并删除onCreateDialog. 但是onCreateView像我解释的那样添加点击侦听器onCreateDialog

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

Then , In your Activityneed to implement an interfaceto handle the action in dialog

然后,在您Activity需要实现一个interface来处理中的动作时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
        }
}

Finally, Show the Dialogfrom your Activitywhen required, like this

最后,在需要时显示Dialog来自您的Activity,像这样

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

Hope this helps. I am sure this approach is one of the optimized way, but there could be also different approaches .

希望这可以帮助。我确信这种方法是一种优化的方法,但也可能有不同的方法。

回答by Karakuri

You can use AlertDialogand AlertDialog.Builder.

您可以使用AlertDialogAlertDialog.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();

回答by duggu

try below code:

试试下面的代码:

calling way

调用方式

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

class CustomDialog

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

回答by jojo

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

}

}

}

回答by San Ko Ko

I faced a problem like you. And all in stackoverflow does not meet what I want. So I create my own Dialog Class and it can use like AlertDialog.Builder class.

我遇到了和你一样的问题。而所有在 stackoverflow 中的内容都不符合我想要的。所以我创建了自己的 Dialog 类,它可以像 AlertDialog.Builder 类一样使用。

In my dialogxml.xml

在我的 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>

For Dialog Shape I create just simple shape xml - drconner.xml

对于对话框形状,我只创建了简单的形状 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>

For custom Alert I create Alear.java as follow

对于自定义警报,我创建 Alear.java 如下

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;


    }
}

To use this Alert class, just simple as the use of AlertDialog.Builder class

要使用这个 Alert 类,就像使用 AlertDialog.Builder 类一样简单

for example :

例如 :

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

The main thing is you should call dismiss() function in your onClick. I hope this may help to you. And let me know if this is what you want or not. You can change the layout as you want in dialogxml.xml.

最重要的是你应该在你的 onClick 中调用dismiss() 函数。我希望这对你有帮助。让我知道这是否是您想要的。您可以根据需要在 dialogxml.xml 中更改布局。

回答by Red wine

I have been using this for some time. Calling the alert dialog inside an activity, where alertDialog is a static function in a class called Misc:

我已经使用了一段时间了。在活动中调用警报对话框,其中 alertDialog 是名为 Misc 的类中的静态函数:

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

And the alert dialog function (a static function in a class called Misc:

和警报对话框函数(一个名为 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();
}

But I have just recently converted it to kotlin. Calling the alert dialog (in Kotlin):

但我最近刚刚将其转换为 kotlin。调用警报对话框(在 Kotlin 中):

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

And the alert dialog function (a function in an object called Misc):

和警报对话框函数(一个名为 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()
}

I have also been using a similar method to show a text input dialog.

我也一直在使用类似的方法来显示文本输入对话框。