2
votes

Comment passer des arguments au dialogue sous Android?

J'appelle un dialogue avec des arguments comme suit:

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

Et voici ma classe de dialogue:

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

Mais quand l'orientation des changements d'appareil lors de la rotation, l'application cesse de fonctionner. Cela ne se produit pas si aucun argument n'est passé. Alors, comment passer des arguments et quelle est la meilleure façon de le faire?


7 commentaires

Si l'application s'arrête, la trace de pile devrait être utile, ce qui n'est pas mentionné dans la question


Avez-vous consulté vos journaux. Je pense que le problème est différent.


Si vous utilisez AlertDialog.Builder , je pense que vous pouvez éviter d'utiliser DialogFragment et simplement utiliser AlertDialog .


est-ce utile? Causé par: androidx.fragment.app.Fragment $ InstantiationException: impossible d'instancier le fragment com.example.kotlinapp2.DialogPicker: impossible de trouver le constructeur de fragments MyDialog est en fait DialogPicker


Je veux rendre MyDialog plus complexe, donc je ne pense pas que je puisse simplement utiliser AlertDialog


publier des journaux d'erreurs


Vérifiez ce lien: stackoverflow.com/questions/46551228/...


4 Réponses :


5
votes

Si c'est un fragment, alors il devrait toujours y avoir un constructeur par défaut disponible. Le fait de transmettre des arguments séparément garantira que les arguments sont préservés lors des changements d'état du fragment
Il existe donc une méthode setArgument (Bundle) dans laquelle vous pouvez passer vos paramètres. Donc, ici, votre appel doit être réécrit comme

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

Vous vous appelez Dialog comme ceci:

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

Pour tout fragment, souvenez-vous toujours d'utiliser des arguments pour transmettre les données


4 commentaires

J'ai mis à jour ma réponse. Appelez simplement les choses comme normales. La seule différence est de transmettre les données en arguments au lieu du constructeur


@ AbnerEscócio Vous devriez toujours vérifier si le bundle contient une clé particulière avant d'y accéder comme bundle.contains ("KEY1")


Je ne l'ai pas compris ..., supposons que si j'ajoute de la KEY1 dans un bundle, la boîte de dialogue fonctionne, puis j'appelle une autre boîte de dialogue avec KEY1 , mais avec valeur différente, la nouvelle boîte de dialogue fonctionne toujours, mais le bundle ne contenait-il pas déjà cette clé?


@ user8455110 Je n'ai pas compris le scénario. Veuillez mettre à jour avec un pseudo code.



1
votes

Essayez ce code et passez toutes les données en argument, lorsque j'ai passé un 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);

}

Ici R.layout.dialog_forsurity est une conception de votre boîte de dialogue ... p >


0 commentaires

0
votes

La raison pour laquelle vous devriez passer des paramètres via le bundle est que lorsque le système restaure un fragment (par exemple lors d'un changement de configuration), il restaurera automatiquement votre bundle.

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

À la place de la création de DialogFragment - Vous devez instancier en appelant la méthode statique de sa classe:

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

Et lorsque vous voulez l'afficher, vous appelez:

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

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

    return d;
}

0 commentaires

2
votes

Solution complète utilisant kotlin

Étape 1. Créez votre classe comme suit

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

Étape 2. Créez l'instance et montrez-la

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

C'est tout!


0 commentaires