简体   繁体   中英

ListAdapter Click event issue using android data-binding + Kotlin + ViewModel

I just started Android development using kotlin lang and facing issue as mentioned below with code

Unable to get click event when using Android ListAdapter with data binding in Kotlin.

Source Code:

list_item_shopping_list_name.xml:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>

        <variable
            name="clickListener"
            type="android.view.View.OnClickListener" />


        <variable
            name="shoppingListName"
            type="com.vp.shoppinglist.database.entity.ShoppingListName" />
    </data>


    <com.google.android.material.card.MaterialCardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="8dp"
        android:layout_marginLeft="16dp"
        android:layout_marginTop="70dp"
        android:layout_marginRight="16dp"
        android:layout_marginBottom="16dp"
        android:onClick="@{clickListener}">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#FFFFFF"
            android:orientation="vertical">

            <com.google.android.material.textfield.TextInputLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

                <com.google.android.material.textfield.TextInputEditText
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:focusable="false"
                    android:text="@{shoppingListName.name}" />
            </com.google.android.material.textfield.TextInputLayout>

        </LinearLayout>

    </com.google.android.material.card.MaterialCardView>
</layout>

Adapter Code:

class ShoppingListNameAdapter(var context: Context) :
ListAdapter<ShoppingListName, ShoppingListNameAdapter.ViewHolder>(ShoppingListNameDiffCallback()) {

private val TAG = javaClass.simpleName

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {

    var inflater = LayoutInflater.from(parent.context)
    var binding = ListItemShoppingListNameBinding.inflate(inflater, parent, false)
    return ViewHolder(binding)
}

override fun onBindViewHolder(holder: ViewHolder, position: Int) {

    getItem(position).let { shoppingListName ->
        holder.apply {
            bind(createOnClickListener(shoppingListName), shoppingListName)
            itemView.tag = holder
        }
    }
}


class ViewHolder(var binding: ListItemShoppingListNameBinding) : RecyclerView.ViewHolder(binding.root) {

    fun bind(listener: View.OnClickListener, item: ShoppingListName) {
        binding.apply {
            with(binding) {
                clickListener = listener
                shoppingListName = item
                executePendingBindings()
            }
        }
    }

}


private fun createOnClickListener(shoppingListName: ShoppingListName): View.OnClickListener {
    return View.OnClickListener {
        Log.e("Click", "==========OnClickListener")
        Toast.makeText(context, "Clicked : ${shoppingListName.name}", Toast.LENGTH_LONG).show()
    }
}


class ShoppingListNameDiffCallback : DiffUtil.ItemCallback<ShoppingListName>() {
    override fun areItemsTheSame(oldItem: ShoppingListName, newItem: ShoppingListName): Boolean {
        return oldItem.name == newItem.name
    }

    override fun areContentsTheSame(oldItem: ShoppingListName, newItem: ShoppingListName): Boolean {
        return oldItem.equals(newItem)
    }
}


}

Can someone help me to fix my issue. Kindly let me know if any other information required about code/project.

Thanks in advance

You can set your listener at you ViewModel like this

interface YourViewModel {
   fun itemClicked()
}

class YourViewModelImpl : YourViewModel {

   override fun itemClicked() {
     // your code after clicked
   }

}

and then your xml is

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>

        <variable
            name="viewModel"
            type="YourViewModel" />


        <variable
            name="shoppingListName"
            type="com.vp.shoppinglist.database.entity.ShoppingListName" />
    </data>


    <com.google.android.material.card.MaterialCardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="8dp"
        android:layout_marginLeft="16dp"
        android:layout_marginTop="70dp"
        android:layout_marginRight="16dp"
        android:layout_marginBottom="16dp"
        android:onClick="@{() -> viewModel.itemClicked(shoppingListName)}">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#FFFFFF"
            android:orientation="vertical">

            <com.google.android.material.textfield.TextInputLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

                <com.google.android.material.textfield.TextInputEditText
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:focusable="false"
                    android:text="@{shoppingListName.name}" />
            </com.google.android.material.textfield.TextInputLayout>

        </LinearLayout>

    </com.google.android.material.card.MaterialCardView>
</layout>

and then you need only set you listener in viewHolder for dataBinding

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