3

When I click on the button for the first time, it runs normally. But when I click on it for the second time, the program crashes: The specified child already has a parent. You must call removeView() on the child's parent first.

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {

        binding = ActivityMainBinding.inflate(layoutInflater)
        super.onCreate(savedInstanceState)
        setContentView(binding.root)

        val view1 = layoutInflater.inflate(R.layout.main_view1, null, false)

        val btn1 = view1.findViewById<Button>(R.id.btn1)
        val btn2 = view1.findViewById<Button>(R.id.btn2)
        val btn3 = view1.findViewById<Button>(R.id.btn3)

        btn1.setOnClickListener {
            binding.textView.setTextColor(Color.RED)
        }
        btn2.setOnClickListener {
            binding.textView.setTextColor(Color.BLUE)
        }
        btn3.setOnClickListener {
            binding.textView.setTextColor(Color.GREEN)
        }

        binding.button.setOnClickListener {

            AlertDialog.Builder(this)
                .setTitle("Color")
                .setView(view1)
                .setCancelable(false)
                .setPositiveButton("ok", DialogInterface.OnClickListener { _, _ ->
                })
                .create().show()
        }

    }
}
Ryan M
  • 18,333
  • 31
  • 67
  • 74
AmirKam
  • 29
  • 1
  • 3
  • 1
    Does this answer your question? [The specified child already has a parent. You must call removeView() on the child's parent first (Android)](https://stackoverflow.com/questions/28071349/the-specified-child-already-has-a-parent-you-must-call-removeview-on-the-chil) – Anand Jun 10 '21 at 01:58
  • That duplicate isn't quite right. This is not the same problem, even if it's the same crash. – Ryan M Jun 10 '21 at 15:30

1 Answers1

1

The problem is that you're creating and holding a reference to view1 once:

    val view1 = layoutInflater.inflate(R.layout.main_view1, null, false)

but then trying to use that same view every time the button is clicked:

    binding.button.setOnClickListener {

        AlertDialog.Builder(this)
            .setTitle("Color")
            .setView(view1)
            .setCancelable(false)
            .setPositiveButton("ok", DialogInterface.OnClickListener { _, _ ->
            })
            .create().show()
    }

To solve it, you should move your setup code inside the button click listener, so that you get a fresh view1 for each new AlertDialog:

    binding.button.setOnClickListener {
        val view1 = layoutInflater.inflate(R.layout.main_view1, null, false)

        val btn1 = view1.findViewById<Button>(R.id.btn1)
        val btn2 = view1.findViewById<Button>(R.id.btn2)
        val btn3 = view1.findViewById<Button>(R.id.btn3)

        btn1.setOnClickListener {
            binding.textView.setTextColor(Color.RED)
        }
        btn2.setOnClickListener {
            binding.textView.setTextColor(Color.BLUE)
        }
        btn3.setOnClickListener {
            binding.textView.setTextColor(Color.GREEN)
        }

        AlertDialog.Builder(this)
            .setTitle("Color")
            .setView(view1)
            .setCancelable(false)
            .setPositiveButton("ok", DialogInterface.OnClickListener { _, _ ->
            })
            .create().show()
    }
Ryan M
  • 18,333
  • 31
  • 67
  • 74