5

I am calling a dialog with arguments as follows:

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

And this is my dialog class:

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

But when the orientation of device changes on rotation, the app stops working. That doesn't happen if no arguments are passed. So, how to pass arguments and what is the best way to do so?

Akshdeep Singh
  • 1,301
  • 1
  • 19
  • 34

4 Answers4

7

If its a fragment, then there should be always a default constructor available. Passing arguments separate will ensure that the arguments are preserved across state changes of the fragment
So there is a method setArgument(Bundle) in which you can pass your parameters. So here your call should be rewritten as

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

You call you Dialog like this:

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

For any fragment always remember to use arguments to pass data

Akshdeep Singh
  • 1,301
  • 1
  • 19
  • 34
Jude Osbert K
  • 940
  • 9
  • 22
  • 1
    I have updated my answer. Just call things as normal. The only difference is passing data in arguments instead of constructor – Jude Osbert K Jun 11 '19 at 12:30
  • @AbnerEscócio You should always check if the bundle contains a particular key before accessing it like bundle.contains("KEY1") – Jude Osbert K Jun 12 '19 at 05:23
  • I didn't get it... , suppose if I add some `KEY1` in a bundle, the dialog works, and then I call some another dialog with `KEY1`, but with different value, the new dialog still works, but wasn't the bundle already containing that key? – Akshdeep Singh Jun 12 '19 at 07:27
  • @user8455110 I did not understand the scenario. Please update with a pseduo code. – Jude Osbert K Jun 12 '19 at 08:47
7

Full solution using kotlin

Step 1. Create your class like follow

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

Step 2. Create the instance and show it

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

It's all!

Abner Escócio
  • 2,697
  • 2
  • 17
  • 36
1

Try this code and pass any data as argument, as i passed a message...

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

}

Here R.layout.dialog_forsurity is a design of your dialog...

Hitesh Kushwah
  • 1,351
  • 13
  • 23
1

The reason why you should be passing parameters through bundle is because when the system restores a fragment (e.g on config change), it will automatically restore your bundle.

Source: https://stackoverflow.com/a/16042750/619673

Instead of creating DialogFragment - You should instantiate by invoking static method from it's class:

public static MyDialog newInstance(String param1) {
    MyDialog d = new MyDialog ();

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

    return d;
}

And when You want to show it, You call:

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

Source: https://stackoverflow.com/a/15463986/619673

deadfish
  • 11,996
  • 12
  • 87
  • 136