【问题标题】:How to pass arguments to dialog in android?如何将参数传递给android中的对话框?
【发布时间】:2019-06-11 11:55:56
【问题描述】:

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

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

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

【问题讨论】:

  • 如果应用停止......堆栈跟踪应该很有用,问题中没有提到
  • 你查过你的日志吗?我认为问题有所不同。
  • 如果你使用AlertDialog.Builder,我认为你可以避免使用DialogFragment,而直接使用AlertDialog
  • 这有帮助吗? Caused by: androidx.fragment.app.Fragment$InstantiationException: Unable to instantiate fragment com.example.kotlinapp2.DialogPicker: could not find Fragment constructorMyDialog 其实就是DialogPicker
  • 我想让MyDialog更复杂,所以我不认为我可以只使用AlertDialog

标签: android kotlin android-dialogfragment


【解决方案1】:

如果它是一个片段,那么应该总是有一个可用的默认构造函数。 单独传递参数将确保在片段的状态更改时保留参数
所以有一个方法 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()
        }
    }
}

你这样称呼你 Dialog:

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

对于任何片段,请始终记住使用参数来传递数据

【讨论】:

  • 我已经更新了我的答案。只是把事情说成是正常的。唯一的区别是在参数而不是构造函数中传递数据
  • @AbnerEscócio 您应该始终检查捆绑包是否包含特定密钥,然后再访问它,例如 bundle.contains("KEY1")
  • 我没听懂...,假设如果我在一个包中添加一些KEY1,该对话框可以工作,然后我用KEY1 调用另一个对话框,但具有不同的值,新对话框仍然有效,但捆绑包中不是已经包含该键吗?
  • @user8455110 我不明白这个场景。请使用伪代码更新。
【解决方案2】:

使用 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)
            }
        }
    }
}

第 2 步。创建实例并显示它

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

就是这样!

【讨论】:

    【解决方案3】:

    试试这个代码并传递任何数据作为参数,因为我传递了一条消息......

        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 是您的对话框设计...

    【讨论】:

      【解决方案4】:

      你应该通过bundle传递参数的原因是因为当系统恢复片段时(例如配置更改),它会自动恢复你的bundle。

      来源:https://stackoverflow.com/a/16042750/619673

      而不是创建 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://stackoverflow.com/a/15463986/619673

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-05-06
        • 2017-05-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-03
        • 1970-01-01
        相关资源
        最近更新 更多