我正在android中开发一个电子商务应用程序,我使用Recyclerview来显示产品。每张卡上都有一个计数器可以增加/减少数量。
我的适配器代码:
class testadapter(
private val context: Context,
private val todaylist: ArrayList<TodaydealItem>
) :
RecyclerView.Adapter<testadapter.MyView>() {
class MyView(itemView: View) : RecyclerView.ViewHolder(itemView) {
var prodid: TextView = itemView.findViewById(R.id.prodid)
var qty: EditText = itemView.findViewById(R.id.qty)
var sub: Button = itemView.findViewById(R.id.sub)
var add: Button = itemView.findViewById(R.id.add)
}
private val quantityMap: HashMap<String, Int> = HashMap()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyView {
val itemView = LayoutInflater.from(parent.context)
.inflate(R.layout.testlayout, parent, false)
return MyView(itemView)
}
override fun onBindViewHolder(holder: MyView, position: Int) {
val currentItem = todaylist[position]
val resources = context.resources
val producturl =
resources.getString(R.string.domain_url) + "api/v2/products/" + currentItem.id
holder.prodid.text = currentItem.id
val quantity = quantityMap[currentItem.id] ?: 1
holder.qty.setText(quantity.toString())
holder.add.setOnClickListener {
val currcount = holder.qty.text.toString()
val currcountasnum: Int? = currcount.toIntOrNull()
val stringRequest = StringRequest(
Request.Method.GET,
producturl,
{ s: String? ->
try {
val jsonObject = JSONObject(s.toString())
val dataArray = jsonObject.getJSONArray("data")
if (dataArray.length() > 0) {
val dataObject = dataArray.getJSONObject(0)
if (dataObject.has("current_stock")) {
val currentStock = dataObject.getInt("current_stock")
if (currcountasnum!! < currentStock) {
holder.qty.setText((currcountasnum + 1).toString())
} else {
Toast.makeText(
context,
"Maximum Stock Reached!",
Toast.LENGTH_LONG
).show()
}
}
}
} catch (e: JSONException) {
e.printStackTrace()
}
}
) { volleyError: VolleyError ->
Toast.makeText(context, volleyError.message, Toast.LENGTH_LONG).show()
}
val requestQueue = Volley.newRequestQueue(context)
requestQueue.add(stringRequest)
}
holder.sub.setOnClickListener {
val currcount = holder.qty.text.toString()
val currcountasnum: Int? = currcount.toIntOrNull()
if (currcountasnum!! > 1) {
holder.qty.setText((currcountasnum - 1).toString())
} else {
holder.qty.setText((currcountasnum - 1).toString())
}
}
}
override fun getItemCount(): Int {
return todaylist.size
}
}
问题是,当我通过增加计数器添加一些项目时,如果滚动它会自动返回到 0。有什么办法可以阻止这种情况并保持数量不变吗?
我在没有哈希图的情况下尝试过。保留数据。但是,在这种方法中,不止一种产品的数量会发生变化,甚至无需触及它们。
我认为你只需通过调用
holder.qty.setText()
来更新ViewHoler上的数据,所以当滚动时onBindViewHolder将从quantityMap
获取值并重新渲染
您应该更新
todaylist
并调用notifyItemChanged来重新渲染此视图持有者。我认为不需要使用HashMap来存储数量,应该只使用一个集合来加载列表数据,可以将字段数量创建到todayList
的项目中
override fun onBindViewHolder(holder: MyView, position: Int) {
//...
holder.add.setOnClickListener {
if (currcountasnum!! < currentStock) {
todaylist[position].quantity = (currcountasnum + 1).toString()
notifyItemChanged(position)
}
}
}
由于 MVC 的规则,我不会在适配器内添加任何实际的单击侦听器。我所拥有的是在适配器内部调用的回调,并且调用函数会监听。
所以在适配器内部,我有类似的东西:
class SomeAdapter(val itemLst: MutableList<ItemModel>, val ctx: FragmentActivity) : RecyclerView.Adapter<SomeAdapter.ViewHolder>(){
private lateinit var binding: AdapterItemBinding
var onItemClick: ((ItemModel) -> Unit)? = null
var onCloseClick: ((ItemModel, Int) -> Unit)? = null
...usual boiler plate
override fun onBindViewHolder(holder: SomeAdapter.ViewHolder, position: Int) {
val item = itemLst[position]
holder.bind(item)
}
inner class ViewHolder(private val binding: AdapterSocketNotifBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(item: ItemModel){
binding.item = item
//the important part for this question
binding.someView.setOnClickListener{
onCloseClick?.invoke(itemLst[adapterPosition], adapterPosition)
}
}
//and this
init {
itemView.setOnClickListener {
onItemClick?.invoke(itemLst[adapterPosition])
}
}
}
}
然后在调用方,无论您在何处实例化此适配器:
itemAdapter.onCloseClick = { it, pos ->
run {
//do whatever you want here
}
}
对于单参数点击监听器来说,就简单多了
itemAdapter.onClick = {
//the variable it would automatically be equal to SomeItem
}
我知道这个答案看起来很复杂,但我想展示的是一种让您可以轻松访问
Fragment
或 Activity
变量的方法,这样您就不必担心如何更新您的适配器可能无法轻松访问的变量。
您必须将计数器值存储在列表的模型类中,因此每当您从
onBindViewHolder()
中获取值时,它都会获得正确的值并且不会重置计数器。是的,当您更改点击计数器时,您必须执行 notifyItemChanged(position)
。