我有一个recyclerView,它显示了购物车项目列表,每个项目都是可点击的,并打开了该项目的详细信息片段,我正在更新项目布局,使其内部有一个删除按钮,删除按钮应该调用片段viewModel中的一个方法。我认为在适配器中将viewModel作为一个构造函数并不是最佳实践,因为在我发展技能的过程中,关注点的分离很重要。
我正在用dataBinding做这件事,我已经搜索了很多,但没有找到答案。
购物车列表项目.xml
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="makeupItem"
type="com.melfouly.makeupshop.model.MakeupItem" />
<variable
name="viewModel"
type="com.melfouly.makeupshop.makeupcart.CartViewModel" />
</data>
<com.google.android.material.card.MaterialCardView
android:id="@+id/cart_card_item"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_margin="4dp"
android:backgroundTint="@color/primary"
app:cardCornerRadius="8dp"
app:cardElevation="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="6">
<ImageView
android:id="@+id/item_image"
loadImage="@{makeupItem}"
android:layout_gravity="center"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:scaleType="fitCenter"
tools:src="@tools:sample/avatars" />
<TextView
android:id="@+id/item_name"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:fontFamily="@font/aclonica"
android:gravity="center"
android:text="@{makeupItem.name}"
android:textColor="@color/black"
android:textStyle="bold"
tools:text="Item name" />
<TextView
android:id="@+id/item_price"
loadPrice="@{makeupItem}"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:fontFamily="@font/aclonica"
android:gravity="center"
android:textColor="@color/black"
tools:text="5$" />
<Button
android:id="@+id/delete_button"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:onClick="@{() -> viewModel.deleteItemFromCart(makeupItem)}"
app:icon="@drawable/ic_baseline_delete_outline_24"
app:iconGravity="end" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</layout>
推车适配器
class CartAdapter(private val clickListener: (MakeupItem) -> Unit) :
ListAdapter<MakeupItem, CartAdapter.CartViewHolder>(DiffCallback()) {
class CartViewHolder(private val binding: CartListItemBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(makeupItem: MakeupItem) {
binding.makeupItem = makeupItem
binding.executePendingBindings()
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CartViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val binding = CartListItemBinding.inflate(layoutInflater, parent, false)
return CartViewHolder(binding)
}
override fun onBindViewHolder(holder: CartViewHolder, position: Int) {
val makeupItem = getItem(position)
holder.itemView.setOnClickListener {
clickListener(makeupItem)
}
holder.bind(makeupItem)
}
class DiffCallback : DiffUtil.ItemCallback<MakeupItem>() {
override fun areItemsTheSame(oldItem: MakeupItem, newItem: MakeupItem): Boolean {
return oldItem.id == newItem.id
}
override fun areContentsTheSame(oldItem: MakeupItem, newItem: MakeupItem): Boolean {
return oldItem == newItem
}
}
CartViewModel删除函数
fun deleteItemFromCart(makeupItem: MakeupItem) {
viewModelScope.launch {
Log.d(TAG, "DeleteItemFromCart method in viewModel called")
repository.deleteItemFromCart(makeupItem)
}
}
1条答案
按热度按时间olhwl3o21#
我有答案了。
viewModel与recyclerView项的DataBinding将不起作用,因为我们没有在此viewModel中声明适配器,因此您应该在适配器中进行回调,并在片段中接收它,然后调用viewModel函数。
以下是修改了单击上的删除按钮的回调后的CartAdapter,并对cardItem使用相同的方法
对于CartListItem,添加两个dataBinding,一个用于itemClickListener,另一个用于deleteButtonClickListener,并在其中使用android:onClick和lambda表达式
到达片段并声明适配器后,传递适配器参数,这些参数将执行特定的viewModel函数或每次单击cardItem和delete按钮时需要实现的任何功能
我希望这是最好的实践答案,并帮助每个人都有同样的问题。