Custom Android view has wrong type when inflating from XML

I have a custom view, that extends LinearLayout:

class MyCustomView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null
) : LinearLayout(context, attrs) {

    private val binding = MyCustomViewBinding.inflate(LayoutInflater.from(context), this, true)
    
    // ...
}

And I need to define a custom wrapper (similar to TextInputLayout), that can include a child MyCustomView object and has a special logic to inflate it. So I want to be able to define the views in XML as follows:

<com.example.MyCustomWrapper 
         android:layout_width="match_parent"
         android:layout_height="wrap_content">

     <com.example.MyCustomView
             android:layout_width="match_parent"
             android:layout_height="wrap_content"/>

 </com.example.MyCustomWrapper>

For that purpose I override addView() method (similar to https://android.googlesource.com/platform/frameworks/support/+/81fdc55/design/src/android/support/design/widget/TextInputLayout.java#140 ), that is called during XML inflation:

class MyCustomWrapper @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null
) : ConstraintLayout(context, attrs) {

    private val binding = MyCustomWrapper Binding.inflate(LayoutInflater.from(context), this, true)
    
    override fun addView(child: View?) {
        if (child is MyCustomView) {
            // custom logic
        } else {
            super.addView(child)
        }
    }
}

Unfortunately, it doesn’t work: the condition child is MyCustomView is always false, in debugger child is only typed as LinearLayout. Any ideas, how to fix this?

Answer

you have to override

override fun addView(child: View?, params: ViewGroup.LayoutParams?) {
    ...
}

addView(child: View?) is invoked only for your MyCustomWrapperBinding

Leave a Reply

Your email address will not be published. Required fields are marked *