Edited at

Android で出た The specified child already has a parent のメモ

コードは kotlin です。

-
version

compile sdk
28

kotlin
1.2.60

(なんのバージョンを書くべきかもあまりよく分かっていない...)


The specified child already has a parent

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

Fragment の中で DataBindingUtil.infrate を使っているときに発生した。


原因

Activity 側で


Activity

        supportFragmentManager

.beginTransaction()
.replace(R.id.dialog_container, XxxxDialogFragment())
.commit()

として、親が R.id.dialog_container だと決まっているのに


XxxxDialogFragment

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {

super.onCreateView(inflater, container, savedInstanceState)

binding = DataBindingUtil.inflate(inflater, R.layout.dialog_xxxx, container, true)


attachToParent = true (例中の inflate の最後の引数) にしてしまったこと。


対処

このケースでは、単に false にすればこのエラーは出ない

もしくは、 Activity 側では親を決めずに


Activity

        supportFragmentManager

.beginTransaction()
.add(XxxxDialogFragment(), "xxxx_dialog")
.commit()

としておいて、 Fragment 側で


XxxxDialogFragment

        val container = activity!!.findViewById<ViewGroup>(R.id.dialog_container) // なんらかの方法で親を拾ってくる

binding = DataBindingUtil.inflate(inflater, R.layout.dialog_xxxx, container, true)


とする。最初の例と違って、 onCreateView の container はおそらく null になっているはずなので、親とする ViewGroup を findViewById で探してくる必要がある。そう考えると onCreateView 以外のメソッドでやってもそんなに違和感はない。


( DataBinding で苦しみまくっているので、この記事はタイトルを変えて他のエラーも色々と載せる記事へと変貌するかもしれないです)