How to do latest jetpack "View binding" in adapter, bind the views?

DevAnuragGarg picture DevAnuragGarg · Mar 2, 2020 · Viewed 7.2k times · Source

How to do latest jetpack "View binding" in adapter, for automatically binding the views. I am not using the findVeiwById or Butterknife or Kotlin synthetic??? I have used the new view binding and is is working fine for Activity and for Fragment. I am able to see the ActivityHomeBinding and FragmentHomeBinding files after enabling the viewBinding in build.gradle file. Also, I am seeing the class ItemListBinding for the item xml used i.e. item_list.xml. But how to use this file in the adapter of the recyclerview

viewBinding {
        enabled = true
}

Home Activity file

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityHomeBinding.inflate(layoutInflater)
        setContentView(binding.root)
}

Fragment

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        binding = FragmentHomeBinding.inflate(inflater, container, false)
        val view = binding.root
        return view
}

Base Adapter: Want to use view binding here. I am able to see ItemListBinding, but not getting how to use it.

class BaseAdapter @Inject constructor(
    private val context: Context,
    private val picasso: Picasso
) :
    RecyclerView.Adapter<BaseAdapter.ViewHolder>() {

    private var data = ArrayList<Data>()

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        return ViewHolder(
            LayoutInflater.from(context).inflate(R.layout.item_list, parent, false)
        )
    }

    override fun getItemCount() = data.size

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        with(holder) {
              // TODO
        }
    }

    class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {

        @BindView(R.id.tvMovieName)
        lateinit var nameTV: TextView

        @BindView(R.id.imageView)
        lateinit var bannerImage: ImageView

        init {
            ButterKnife.bind(this@ViewHolder, view)
        }
    }

    fun setData(serverData: ArrayList<Data>) {
        data = serverData
        notifyDataSetChanged()
    }
}

Answer

Pawel picture Pawel · Mar 2, 2020

You can use static bind method of ViewBinding to create binding from already existing layout. Add it as a property to viewholder:

class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
   val binding = ItemListBinding.bind(view)
}

then you can access all the views through the binding field, for example:

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    with(holder) {
          // TODO
          binding.tvMovieName.text = data[position].title
          binding.imageView.setDrawableImage(data[position].image)
    }
}