【问题标题】:Create a general class for custom Dialog in java Android在java Android中为自定义Dialog创建一个通用类
【发布时间】:2014-05-01 13:31:54
【问题描述】:

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

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

这是我目前的课程:

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

}

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

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

我确信它是可以改进的,但是你怎么能这样做呢?

谢谢

【问题讨论】:

  • 为什么有人投了-1票?这是一个合理的问题。

标签: java android generics dialog


【解决方案1】:

首先创建一个 Base DialogFragment 以保留 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;
        }
}

然后,创建一个扩展 BaseDialogFragmentGeneralDialogFragment

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

    }

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

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

那么,在你的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
        }
}

最后,在需要时显示Activity 中的Dialog,像这样

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

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

【讨论】:

  • 利宾,确实是个好主意,但并不通用。我的意思是 setPositiveButton 和 setNegativeButton 的 onClick 事件可以改变。想象一下,我有 10 个看起来相同的对话框,但取决于活动/屏幕的位置,当我单击“是”时,所有这些活动都会有所不同。
  • 好的。我会更新答案。你对 Dialog Fragment 还满意吗?
  • 好吧,我想工作 4.0 android 版本。
  • 对不起,我需要一些时间来吃它,当我第一次看到它时有点难......无论如何,这是我正在寻找的一个很好的方法,通用代码。关键是将 onClick 事件链接到接口函数并有一个基本对话框......非常明智。我还没有检查它,但我会接受它作为一个真正的答案。谢谢
  • @Libin 我如何在 Fragment 上使用它?
【解决方案2】:

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

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

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

对于自定义警报,我按如下方式创建 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;


    }
}

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

例如:

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

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

【讨论】:

  • 这正是我所需要的...非常感谢!
  • 这对我有用,但我不得不删除 requestWindowFeature(Window.FEATURE_NO_TITLE);,因为它产生了错误
【解决方案3】:

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

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

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

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

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

还有alert dialog函数(一个叫做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()
}

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

【讨论】:

  • 这就是我想要的:如何将 OnClickListener 作为参数推送。谢谢!
【解决方案4】:

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

【讨论】:

  • 但它不是具有自定义布局的自定义对话框。 AlertDialog 的默认主题真的很丑。
【解决方案5】:

试试下面的代码:

调用方式

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

自定义对话框类

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

【讨论】:

  • 和利宾是一样的想法。 Onclick 事件无法更改。我希望能够更改是或否事件的功能,但我希望在所有事件中都使用相同的对话框。就像重写onclick函数并在类中有抽象函数......但我不知道如何获得它。
【解决方案6】:
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);

}

}

【讨论】:

  • 虽然代码很受欢迎,但它应该始终有一个附带的解释。这不必很长,但在意料之中。
猜你喜欢
  • 1970-01-01
  • 2014-08-01
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-30
  • 2017-10-07
相关资源
最近更新 更多