简体   繁体   中英

Refactor my viewholder class in kotlin

I have a recycler list which holds many different types of item views. It is quite easy to use databinding without necessary to declare the layout and assignment in the viewholder, however I end up with many biloplate code to just create the different viewholders with databinding, is there a way to get rid of them?

class ViewHolder1 private constructor(
    val binding: ViewHolder1LayoutBinding
): RecyclerView.ViewHolder(binding.root) {
    companion object {
        fun create(parent: ViewGroup): RecyclerView.ViewHolder {
            val inflater = LayoutInflater.from(parent.context)
            val binding = ViewHolder1LayoutBinding.inflate(inflater, parent, false)
            return ViewHolder1(binding)
        }
    }

    fun bind(viewModel: ViewHolder1ViewModel) {
        binding.viewModel = viewModel
        binding.executePendingBindings()
    }
}

kotlin supports view binding so no need to do other stuffs for binding view. Just follow steps and you will able to access view by its id defined in xml layout.

In app level gradle add following

apply plugin: 'kotlin-android-extensions'

Import view

import kotlinx.android.synthetic.main.<layout_file>.view.*

Just check this class for demo

class NotificationHolder(itemView: View?, listener: NotificationItemListener) : RecyclerView.ViewHolder(itemView) {
    init {
        itemView?.setOnClickListener {
            listener.onNotificationItemClicked(adapterPosition)
        }
    }

    fun bind(notificationModel: NotificationModel) {
        val titleArray = notificationModel.title.split("#".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
        itemView.tvNotificationTitle.text = titleArray[0]
        itemView.tvNotificationDetails.text = notificationModel.message
        itemView.tvNotificationTime.text = notificationModel.formattedTime
        Glide.with(itemView.context).load(ServiceHandler.BASE_URL + notificationModel.icon).dontAnimate().diskCacheStrategy(DiskCacheStrategy.SOURCE).error(R.drawable.user_default_logo).into(itemView.imageView)
        if (CommonUtils.lastNotificationTime < notificationModel.date) {
            itemView.card.setCardBackgroundColor(Color.parseColor("#ffffff"))
        } else {
            itemView.card.setCardBackgroundColor(Color.parseColor("#f2f2f2"))
        }
    }
}

In adapter you can override

override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): RecyclerView.ViewHolder {
        return if (viewType == 0 || viewType == 3) {
            NotificationHolder(LayoutInflater.from(parent?.context).inflate(R.layout.item_notification, parent, false), this)
        } else {
            NotificationListHeaderHolder(LayoutInflater.from(parent?.context).inflate(R.layout.item_notification_header, parent, false))
        }
    }

override fun onBindViewHolder(holder: RecyclerView.ViewHolder?, position: Int) {
        (holder as? NotificationHolder)?.bind(notificationList[position])
        (holder as? NotificationListHeaderHolder)?.bind(notificationList[position])

    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM