ViewBinding not showing the view in custom views

3.8k Views Asked by At

I'm trying to use ViewBinding in a new module I added to my project that will contain all the CustomViews in the project.

at the moment, this module is the only one that will implement the viewbinding. The main module (app), is using kotlin synthetic.

Originally I have these 2 custom views:

(Pre - ViewBinding --> This is working. I can see it in the fragment attached)

CustomView 1:

import kotlinx.android.synthetic.main.layout_horizontal_filter.view.*

class HorizontalFiltersView @JvmOverloads constructor(
        context: Context,
        attrs: AttributeSet? = null,
        defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr) {

    private val adapter: HorizontalFilterAdapter
    private val decoration: HorizontalFilterDecorator

    init {
        LayoutInflater.from(context).inflate(R.layout.layout_horizontal_filter, this, true)
        this.adapter = HorizontalFilterAdapter(context)
        this.decoration = HorizontalFilterDecorator(context, 16)

        recycler.layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
        recycler.adapter = this.adapter
        recycler.addItemDecoration(this.decoration)
        recycler.setHasFixedSize(true)
    }

    fun setFilters(filtersList: MutableList<HorizontalFilter>) {
        this.adapter.refresh(filtersList)
    }

}

CustomView2:

import kotlinx.android.synthetic.main.item_horizontal_filter.view.*
class HorizontalFilterItem @JvmOverloads constructor(
        context: Context,
        attrs: AttributeSet? = null,
        defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr) {

    private var onClickAction: () -> Unit = {}

    init {
        LayoutInflater.from(context).inflate(R.layout.item_horizontal_filter, this, true)
        setOnClickListener { onClickAction.invoke() }
    }

    fun setData(image: Int, title: String, action: () -> Unit = {}) {
        filter_title.text = title
        loadImage(image)
        setClickAction(action)
    }

    fun setClickAction(action: () -> Unit) {
        this.onClickAction = action
    }

    private fun loadImage(image: Int?) {
        image?.let { img ->
            filter_image?.let { imView ->
                Glide.with(this).load(img).fitCenter().into(imView)
            }
        }
    }
}

Then I added the viewBinding = true in my build.gradle file and deleted the kotlin-android-extensions plugin.

So the Customs looks like:

class HorizontalFiltersView @JvmOverloads constructor(
        context: Context,
        attrs: AttributeSet? = null,
        defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr) {

    private val adapter: HorizontalFilterAdapter
    private val decoration: HorizontalFilterDecorator
    private val binding = LayoutHorizontalFilterBinding.inflate(LayoutInflater.from(context))

    init {
        addView(binding.root)
        this.adapter = HorizontalFilterAdapter(context)
        this.decoration = HorizontalFilterDecorator(context, 16)

        binding.recycler.layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
        binding.recycler.adapter = this.adapter
        binding.recycler.addItemDecoration(this.decoration)
        binding.recycler.setHasFixedSize(true)
    }

    fun setFilters(filtersList: MutableList<HorizontalFilter>) {
        this.adapter.refresh(filtersList)
    }

}

class HorizontalFilterItem @JvmOverloads constructor(
        context: Context,
        attrs: AttributeSet? = null,
        defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr) {

    private val binding = ItemHorizontalFilterBinding.inflate(LayoutInflater.from(context))
    private var onClickAction: () -> Unit = {}

    init {
        addView(binding.root)
        setOnClickListener { onClickAction.invoke() }
    }

    fun setData(image: Int, title: String, action: () -> Unit = {}) {
        binding.filterTitle.text = title
        loadImage(image)
        setClickAction(action)
    }

    fun setClickAction(action: () -> Unit) {
        this.onClickAction = action
    }

    private fun loadImage(image: Int?) {
        image?.let { img ->
            binding.filterImage.let { imView ->
                Glide.with(this).load(img).fitCenter().into(imView)
            }
        }
    }
}

Up to this point, everything works fine. But when I open the fragment, the custom views are not displayed.

So in summary:

With Kotlin synthetic it works and the views are displayed; with ViewBinding it doesn't work.

What is wrong?

2

There are 2 best solutions below

1
On BEST ANSWER

Try replacing this line:

    private val binding = LayoutHorizontalFilterBinding.inflate(LayoutInflater.from(context))

with this:

    private val binding = LayoutHorizontalFilterBinding.inflate(LayoutInflater.from(context), this, true)
0
On

Add container arguments, and attachToParent = true argument when inflating