Search code examples
androidkotlinandroid-alertdialogillegalstateexception

Kotlin dialog java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first


Once the user clicks on change_account on my activity a dialog was shown then once the user clicks on create count on this dialog I want to show another dialog.

But unfortunately I got this error:

E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.

I have seen on the net some code to removeView() but I do not know how to use it. Especially because I call the dialogue from another dialog.

and here is my code the line which causes the error is that one

 creatCount.create().apply { show() }

And here is the complete code:

class ClientAcountActivity : AppCompatActivity(),AdapterView.OnItemClickListener{

    override fun onCreate(savedInstanceState: Bundle?) {

        ....

        change_account.setOnClickListener { openChangeCompte() }

    }


    fun openChangeCompte()
    {
        val dialogBuilder = AlertDialog.Builder(this)
        val inflater = getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
        val row = inflater.inflate(R.layout.dialog_listview, null, false)
        val listAccount= row.findViewById<ListView>(R.id.transfer_type_list)
        Log.d("ClientAccountActivity", Injection.provideAccountRepository().availableAccountsType.toString())
        listAccount.adapter = CountChangeAdapter(Injection.provideAccountRepository().availableAccountsType, this)

       listAccount.onItemClickListener = AdapterView.OnItemClickListener { adapterView: AdapterView<*>, view: View, i: Int, id: Long ->

           if((adapterView.getCount()!=4) && (i==adapterView.getCount()-1))
                {
                     val creatCount: AlertDialog.Builder = AlertDialog.Builder(this).apply {
                           setView(row)
                           setTitle("Quel compte voulez vous créer ")
                           setPositiveButton("OK",  DialogInterface.OnClickListener() {
                               dialogInterface: DialogInterface, i: Int ->
                               fun onClick(dialog:DialogInterface , which:Int) {
                           }})
                           setNegativeButton("Cancel",  DialogInterface.OnClickListener() {
                               dialogInterface: DialogInterface, i: Int ->
                               fun  onClick(dialog:DialogInterface ,  which:Int) {
                                   finish()
                           }})
                       }
                    creatCount.create().apply { show() } //the line which cause the pb 

                }
                else
                {
                    Injection.provideAccountRepository().selectedAccount=id.toInt()
                    updateBalance()
                    changeAccoutDialog!!.dismiss()
                }
            }
        dialogBuilder.setView(row)
        dialogBuilder.setTitle("Quel compte voulez vous choisir?")
        changeAccoutDialog = dialogBuilder.create().apply { show() }
    }
}

Solution

  • The problem here is due to setting the variable row into two dialog's view: you should create a second row (with the same layout using inflater) in order to set it to the second dialog. Here is the code corrected:

    fun openChangeCompte()
    {
        val dialogBuilder = AlertDialog.Builder(this)
        val inflater = getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
        val row = inflater.inflate(R.layout.dialog_listview, null)
        val listAccount= row.findViewById<ListView>(R.id.transfer_type_list)
        Log.d("ClientAccountActivity", Injection.provideAccountRepository().availableAccountsType.toString())
        listAccount.adapter = CountChangeAdapter(Injection.provideAccountRepository().availableAccountsType, this)
    
        listAccount.onItemClickListener = AdapterView.OnItemClickListener { adapterView: AdapterView<*>, view: View, i: Int, id: Long ->
    
            if((adapterView.count !=4) && (i==adapterView.count -1))
            {
                val row2 = inflater.inflate(R.layout.dialog_listview, null)
                val listAccount= row2.findViewById<ListView>(R.id.transfer_type_list)
                val creatCount: AlertDialog.Builder = AlertDialog.Builder(this).apply {
                    setView(row2)
                    setTitle("Quel compte voulez vous créer ")
                    setPositiveButton("OK") { _: DialogInterface, _: Int ->
                        fun onClick(dialog:DialogInterface , which:Int) {
                        }}
                    setNegativeButton("Cancel") { _: DialogInterface, _: Int ->
                        fun  onClick(dialog: DialogInterface, which:Int) {
                            finish()
                        }}
                }
                creatCount.create().apply { show() } //the line wich cause the pb
    
            }
            else
            {
                Injection.provideAccountRepository().selectedAccount=id.toInt()
                updateBalance()
                changeAccoutDialog !!.dismiss()
            }
        }
        dialogBuilder.setView(row)
        dialogBuilder.setTitle("Quel compte voulez vous choisir?")
        changeAccoutDialog = dialogBuilder.create().apply { show() }
    }