Search code examples
androidkotlinandroid-databindingkotlin-extension

Kotlin android extensions in custom view with databinding


I have a Custom Linear layout and an xml file in with 3 checkboxes. The Custom linear layout looks roughly like this:

class AdvancedBox : LinearLayout, DefineExchangesDialog.DefineExchangesDialogListener {

    private lateinit var mBinding: AdvancedBoxBinding

    private lateinit var viewModel: GlobalConfigViewModel

    constructor(c: Context) : super(c) {
        initLayout()
    }

    constructor(c: Context, a: AttributeSet) : super(c, a) {
        initLayout()
    }

    private fun initLayout() {
        val inflater = LayoutInflater.from(context)
        mBinding = AdvancedBoxBinding.inflate(inflater)
    }

    override fun getRootView(): View {
        return mBinding.root
    }

    fun setViewModel(viewModel: GlobalConfigViewModel){
        mBinding.viewModel = viewModel
    }

    override fun onFinishInflate() {
        super.onFinishInflate()

        //cbVolumeChange is an id defined in advanced_box.xml 
        cbVolumeChange.setOnClickListener(this::onShowAdvanced)
        cbExchanges.setOnClickListener(this::onShowAdvanced)
        cbPriceFilter.setOnClickListener(this::onShowAdvanced)
    }  

The problem is that setting an onClickListener on any of the checkboxes in onFinishInflate() will cause a NullPointerException. I thought overriding the getRootView() would be the solution but that did not work. Something that would work is the following

val root = mBinding.root
root.cbVolumeChange ...

But that is not something I would like to do. So what would be the right way to use the Android Kotlin extension with databinding in my case?


Solution

  • The issue is, that the inflated view is not attached to the layout. You should use AdvancedBoxBinding.inflate(inflater, this, true) for it.

    After that onFinishInflate() doesn't matter for you, as it's only relevant for inflating the view and the hierarchy from XML not from code as you're doing.