You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Adapter按钮更新PosActivity中的TextView?

问题描述

我希望点击MyAdapter中的按钮(实现数量增减、删除RecyclerView卡片)时,更新PosActivity内的TextView,但一直找不到解决方法。以下是我尝试的代码:

MyAdapter 代码

package com.mycodlabs.pos.ui.sale.adapter

import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.mycodlabs.pos.R
import com.mycodlabs.pos.domain.inventory.ProductModel
import kotlinx.android.synthetic.main.pos_item_card.view.*
import java.math.BigDecimal

class MyAdapter(mUx: Context, var selectedItems: ArrayList<ProductModel>) : RecyclerView.Adapter<MyAdapter.ViewHolder>() {

    val mUx = mUx
    var totalPrice = BigDecimal.ZERO

    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        var pclose = itemView.removeItempos
        var pname = itemView.pos_name
        var pprice = itemView.pos_price
        var pqty = itemView.pos_qty
        var pminus = itemView.cart_minus_img
        var pplus = itemView.cart_plus_img
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.pos_item_card, parent, false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val pos: ProductModel = selectedItems[position]

        holder.pname.text = pos.name
        holder.pprice.text = pos.unitPrice.toString()
        holder.pqty.text = pos.quantity.toString()

        holder.pclose.setOnClickListener {
            selectedItems.removeAt(position)
            notifyDataSetChanged()
            notifyItemRangeChanged(position, selectedItems.size)
        }

        holder.pminus.setOnClickListener {
            if(pos.quantity > 1 ){
                pos.quantity -= 1
                notifyItemChanged(position)
            }
        }
        holder.pplus.setOnClickListener {
            pos.quantity += 1
            notifyItemChanged(position)
        }
    }

    fun grandTotal(items: ArrayList<ProductModel>): BigDecimal {
        totalPrice = BigDecimal.ZERO
        for (i  in items.indices) {
            totalPrice += items[i].unitPrice.multiply(items[i].quantity.toBigDecimal())
        }
        return totalPrice
    }

    fun clearData() {
        selectedItems.clear()
        notifyDataSetChanged()
    }

    override fun getItemCount() = selectedItems.size
}

PosActivity 代码

package com.mycodlabs.pos.ui

import android.os.Bundle
import android.view.View
import android.widget.*
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.mycodlabs.pos.R
import com.mycodlabs.pos.db.AndroidDatabase
import com.mycodlabs.pos.db.DatabaseTables
import com.mycodlabs.pos.db.inventory.InventoryDbo
import com.mycodlabs.pos.db.sale.SalesLinesDao
import com.mycodlabs.pos.domain.inventory.ProductModel
import com.mycodlabs.pos.ui.sale.adapter.MyAdapter
import kotlinx.android.synthetic.main.activity_pos.*
import kotlinx.android.synthetic.main.adapter_available_promotions.*
import kotlinx.android.synthetic.main.dialog_paymentsuccession.view.*
import kotlinx.android.synthetic.main.dialog_saleedit.*
import kotlinx.android.synthetic.main.layout_addcategory.*
import kotlinx.android.synthetic.main.layout_sale.*
import kotlinx.android.synthetic.main.listview_stock.*
import kotlinx.android.synthetic.main.pos_bottom_sheet.*
import kotlinx.android.synthetic.main.pos_item_card.*

class PosActivity : AppCompatActivity() {

    private lateinit var bottomSheetBehavior: BottomSheetBehavior<LinearLayout>
    private lateinit var recyclerView: RecyclerView
    private lateinit var db: SalesLinesDao
    var selectedItems = ArrayList<ProductModel>()
    val adapter = MyAdapter(this,selectedItems)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_pos)

        back.setOnClickListener {
            finish()
        }

        check_out_Pos.setOnClickListener{
            adapter.clearData()
        }

        val autoCompleteTextView = findViewById<AutoCompleteTextView>(R.id.searchBoxPos)
        val productNames = ArrayList<String>()
        val dbHelper = AndroidDatabase(this)
        val db = dbHelper.readableDatabase
        val cursor = db.rawQuery(
            "SELECT DISTINCT ${InventoryDbo.colm_productName} FROM ${DatabaseTables.TABLE_PRODUCT} WHERE ${InventoryDbo.colm_productName} like '%%'",
            null
        )
        if (cursor.moveToFirst()) {
            do {
                productNames.add(cursor.getString(cursor.getColumnIndex(InventoryDbo.colm_productName)))
            } while (cursor.moveToNext())
        }
        cursor.close()
        db.close()
        val adapterr = ArrayAdapter(this, android.R.layout.simple_dropdown_item_1line, productNames)
        autoCompleteTextView.setAdapter(adapterr)

        val recyclerView = findViewById<RecyclerView>(R.id.sale_List_Pos)
        val layoutManager = LinearLayoutManager(this)
        recyclerView.layoutManager = layoutManager
        recyclerView.adapter = adapter

        searchBoxPos.setOnItemClickListener { _, _, position, _ ->
            val selectedItem = autoCompleteTextView.adapter.getItem(position).toString()
            val selectedProduct = InventoryDbo.getInstance(applicationContext).getPosProductByName(selectedItem).first()
            selectedItems.add(selectedProduct)
            adapter.notifyDataSetChanged()
            searchBoxPos.clearFocus()
            searchBoxPos.setText("")
            total_items_Pos.text = adapter.grandTotal(selectedItems).toString()
        }

        bottomSheetBehavior = BottomSheetBehavior.from<LinearLayout>(std_btm_sht)
        bottomSheetBehavior.setBottomSheetCallback(object :
            BottomSheetBehavior.BottomSheetCallback() {
            override fun onStateChanged(bottomSheet: View, state: Int) {
                when (state) {
                    BottomSheetBehavior.STATE_EXPANDED,
                    BottomSheetBehavior.STATE_COLLAPSED,
                    BottomSheetBehavior.STATE_DRAGGING,
                    BottomSheetBehavior.STATE_SETTLING,
                    BottomSheetBehavior.STATE_HALF_EXPANDED -> {
                        total_items_Pos.text = adapter.grandTotal(selectedItems).toString()
                    }
                    else -> {}
                }
            }

            override fun onSlide(bottomSheet: View, slideOffset: Float) {
            }
        })
    }
}
解决方案:接口回调实现数据同步

要实现Adapter按钮操作实时更新Activity的TextView,通过接口回调是最直接可靠的方式,让Adapter在数据变化时通知Activity更新UI。

步骤1:在MyAdapter中定义回调接口

在MyAdapter类内部添加接口,用于传递数据变更事件:

interface OnItemChangeListener {
    fun onDataChanged() // 数量调整、删除卡片时触发
}

修改Adapter构造函数,传入回调实例:

class MyAdapter(
    mUx: Context, 
    var selectedItems: ArrayList<ProductModel>,
    private val listener: OnItemChangeListener // 新增回调参数
) : RecyclerView.Adapter<MyAdapter.ViewHolder>() {
    // ... 原有代码 ...
}

步骤2:按钮点击时触发回调

修改三个按钮的点击逻辑,每次数据变更后调用回调方法:

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    val pos: ProductModel = selectedItems[position]

    // ... 原有赋值代码 ...

    holder.pclose.setOnClickListener {
        selectedItems.removeAt(position)
        notifyDataSetChanged()
        notifyItemRangeChanged(position, selectedItems.size)
        listener.onDataChanged() // 通知Activity更新
    }

    holder.pminus.setOnClickListener {
        if(pos.quantity > 1 ){
            pos.quantity -= 1
            notifyItemChanged(position)
            listener.onDataChanged() // 通知Activity更新
        }
    }
    holder.pplus.setOnClickListener {
        pos.quantity += 1
        notifyItemChanged(position)
        listener.onDataChanged() // 通知Activity更新
    }
}

步骤3:在PosActivity中实现回调

修改Adapter初始化代码,实现接口并更新TextView:

val adapter = MyAdapter(this, selectedItems, object : MyAdapter.OnItemChangeListener {
    override fun onDataChanged() {
        total_items_Pos.text = adapter.grandTotal(selectedItems).toString()
    }
})

可选优化:减少重复计算

可以在Adapter内部维护总金额,避免每次遍历列表计算,提升性能:

// MyAdapter中新增变量和方法
private var totalPrice = BigDecimal.ZERO

private fun calculateTotal() {
    totalPrice = BigDecimal.ZERO
    selectedItems.forEach { item ->
        totalPrice += item.unitPrice.multiply(item.quantity.toBigDecimal())
    }
}

fun getTotal(): BigDecimal {
    return totalPrice
}

// 按钮点击时先更新总价再触发回调
holder.pclose.setOnClickListener {
    selectedItems.removeAt(position)
    notifyDataSetChanged()
    notifyItemRangeChanged(position, selectedItems.size)
    calculateTotal()
    listener.onDataChanged()
}

// 增减按钮同理...

然后Activity中直接调用getTotal():

override fun onDataChanged() {
    total_items_Pos.text = adapter.getTotal().toString()
}

这样就能实现按钮操作时实时更新Activity中的TextView了。

内容的提问来源于stack exchange,提问作者Abbas Amhaz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 12:02:44