Проблема события ListAdapter Click с использованием привязки данных Android + Kotlin + ViewModel - PullRequest
0 голосов
/ 20 июня 2019

Я только начал разработку Android с использованием kotlin lang и столкнулся с проблемой, как указано ниже с кодом

Невозможно получить событие нажатия при использовании Android ListAdapter с привязкой данных в Kotlin.

Исходный код:

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>

Код адаптера:

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)
    }
}


}

Может кто-нибудь помочь мне решить мою проблему. Пожалуйста, дайте мне знать, если требуется какая-либо другая информация о коде / проекте.

Заранее спасибо

1 Ответ

0 голосов
/ 20 июня 2019

Вы можете настроить свой слушатель на ViewModel следующим образом

interface YourViewModel {
   fun itemClicked()
}

class YourViewModelImpl : YourViewModel {

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

}

и тогда ваш 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="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>

и тогда вам нужно только установить прослушиватель в viewHolder для привязки данных

...