如何在Android中向对话框传递参数?

5

我正在调用一个带有以下参数的对话框:

MyDialog("title", "message").show(this@MyActivity.supportFragmentManager, null)

这是我的对话框类:

class MyDialog(private val theTitle: String, private val theMessage: String) : DialogFragment() {
    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        return activity.let {
            val myBuilder = AlertDialog.Builder(it)
            myBuilder
                .setTitle(theTitle)
                .setMessage(theMessage)
                .setPositiveButton("OK") { _, _ -> }
            myBuilder.create()
        }
    }
}

但是当设备旋转时,应用程序停止工作。如果没有传递参数,则不会发生这种情况。那么,如何传递参数,以及最佳方法是什么?


如果应用程序停止...堆栈跟踪应该很有用,这在问题中没有提到。 - Santanu Sur
你查看了日志吗?我认为问题是另外一件事。 - Umair
1
如果您正在使用 AlertDialog.Builder,我认为您可以避免使用 DialogFragment,直接使用 AlertDialog - Froyo
这有帮助吗?Caused by: androidx.fragment.app.Fragment$InstantiationException: Unable to instantiate fragment com.example.kotlinapp2.DialogPicker: could not find Fragment constructor MyDialog 实际上是 DialogPicker。 - Akshdeep Singh
请查看此链接: https://dev59.com/xlYN5IYBdhLWcg3w_sua#49859403 - Krasavello13
显示剩余2条评论
4个回答

8
如果是片段,则应始终提供默认构造函数。 将参数分开传递将确保在片段的状态更改时保留参数。
因此,有一个名为setArgument(Bundle)的方法,您可以在其中传递参数。 因此,在这里,您的调用应该被重写为
class MyDialog: DialogFragment() {
    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        return activity.let {
             val arg = arguments
            // Use the parameters by accessing the key from variable "arg"
            val myBuilder = AlertDialog.Builder(it)
            myBuilder
                .setTitle(theTitle)
                .setMessage(theMessage)
                .setPositiveButton("OK") { _, _ -> }
            myBuilder.create()
        }
    }
}

你可以像这样调用你的对话框:

val d = MyDialog()
val b = Bundle()
b.putInt("KEY1",1)
d.arguments = b
d.show(FragmentManager,Tag)

对于任何片段(fragment),请记得使用参数来传递数据。


1
我已经更新了我的答案。只需像平常一样调用即可。唯一的区别是将数据作为参数传递而不是构造函数。 - Jude Osbert K
@AbnerEscócio 在访问 bundle 中的某个键值之前,你应该始终检查 bundle 是否包含它,例如 bundle.contains("KEY1")。 - Jude Osbert K
我不明白...假设我在一个bundle中添加了一些KEY1,那么对话框就可以工作了,然后我使用具有不同值的KEY1调用另一个对话框,新的对话框仍然可以工作,但是bundle不是已经包含了那个键吗? - Akshdeep Singh
@user8455110,我不明白这种情况。请更新伪代码。 - Jude Osbert K

7

使用Kotlin的完整解决方案

步骤1. 创建如下类

class MyDialog : DialogFragment() {

    private var title: String? = null
    private var message: String? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        arguments?.let {
            title = it.getString(ARG_TITLE)
            message = it.getString(ARG_MESSAGE)
        }
    }

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        return activity.let {
            val myBuilder = AlertDialog.Builder(it)
                myBuilder
                    .setTitle(title)
                    .setMessage(message)
                    .setPositiveButton("OK") { _, _ -> }
            myBuilder.create()
        }
    }

    companion object {
        const val TAG = "myDialog"
        private const val ARG_TITLE = "argTitle"
        private const val ARG_MESSAGE = "argMessage"

        fun newInstance(title: String, message: String) = MyDialog().apply {
            arguments = Bundle().apply {
                putString(ARG_TITLE, title)
                putString(ARG_MESSAGE, message)
            }
        }
    }
}

第二步。 创建实例并展示

MyDialog.newInstance("title", "message").show(this@MyActivity.supportFragmentManager, MyDialog.TAG)

就这些!


1
尝试使用此代码并将任何数据作为参数传递,就像我传递了一条消息一样...
    private void confirmdialog(String msg_str) {

    final Dialog dialog = new Dialog(this);
    dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
    dialog.setCancelable(false);
    dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
    LayoutInflater li = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View v1 = li.inflate(R.layout.dialog_forsurity, null, false);
    dialog.setContentView(v1);
    dialog.setCancelable(true);


    TextView msg = (TextView) v1.findViewById(R.id.msg);
    msg.setText(msg_str);

    Button btn_submit = (Button) v1.findViewById(R.id.btn_submit);


    btn_submit.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            dialog.dismiss();

            Intent intent = new Intent(SellNumberPlateActivity.this, HomeActivity.class);
            startActivity(intent);
            finishAffinity();

        }
    });

    dialog.show();
    Window window = dialog.getWindow();
    window.setLayout(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);

}

这里的 R.layout.dialog_forsurity 是您对话框的设计...

1
你应该通过bundle传递参数的原因是,当系统恢复片段时(例如在配置更改时),它将自动恢复你的bundle。
来源: https://dev59.com/Xmct5IYBdhLWcg3wetUo#16042750 不要创建DialogFragment - 你应该通过调用其类的静态方法来实例化。
public static MyDialog newInstance(String param1) {
    MyDialog d = new MyDialog ();

    Bundle args = new Bundle();
    args.putString("param1", param1);
    d.setArguments(args);

    return d;
}

当您想要展示它时,您会调用:

MyDialog dialog = MyDialog .newInstance("lorem ipsum");
dialog.show(fm, "fragment_confirm_dialog");

来源:https://dev59.com/P2_Xa4cB1Zd3GeqP4sXj#15463986


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接