首页 > 解决方案 > 如何遍历 recyclerview 适配器中的项目获取结果并将其传递给片段

问题描述

下面是我的 recyclerview 适配器,每当填充我的 recyclerview 时,我都会遍历所有视图并计算总收入和支出,并在名为 MainAccountBalance 的变量中获取余额。如何将此变量值传递给我的 Mainfragment,以便我可以在 recyclerview 顶部的 textview 上显示它?任何时候 recyclerview 项目发生变化,或者 recyclerview 填充/重新填充变量都应该在 textview 上自动传递和更新。

我对此很陌生,非常感谢 Kotlin 详细的代码。谢谢。

class RecyclerViewAdapter(options: FirestoreRecyclerOptions<DataModel>) : FirestoreRecyclerAdapter<DataModel,  RecyclerViewAdapter.MyViewHolder>(options) {
  private var listener: OnItemClickListener? = null
   private  var MainAccountBalance: Double = 0.00




    override fun onBindViewHolder(holder: MyViewHolder, position: Int, model: DataModel) {
        holder.noteTextView.setText(model.transaction_note)
        holder.transactionDateTextView.setText(model.transaction_timestamp?.let { convertLongToDateString(it) }).toString()

        var totalIncome: Double = 0.0
        var totalexpense: Double = 0.0

        // change the money to red or blue based on the transaction type
        val transaction_type = model.transaction_type
        if (transaction_type=="expense") {
            holder.amountTextView.setTextColor(Color.parseColor("#D12E9A"));
            holder.amountTextView.text = model.transaction_amount?.let { replaceArabicNumbers(convertIntToCurrencyString(it)) }
            totalexpense =model.transaction_amount!! + totalexpense

        }
        else {
            holder.amountTextView.setTextColor(Color.parseColor("#3A86FF"))
            holder.amountTextView.text = model.transaction_amount?.let { replaceArabicNumbers(convertIntToCurrencyString(it)) }
            totalIncome = model.transaction_amount!! + totalIncome
        }
    MainAccountBalance = totalIncome - totalexpense



}

public fun replaceArabicNumbers(original: kotlin.String): kotlin.String {
    return original
        .replace("٠","0")
        .replace("١","1")
        .replace("٢","2")
        .replace("٣","3")
        .replace("٤","4")
        .replace("٥","5")
        .replace("٦","6")
        .replace("٧","7")
        .replace("٨","8")
        .replace("٩","9")
        // arabic decimal point = U+066B
        .replace("٫",".")
        // thousands grouping seperator = U+066C
        .replace("٬",",")
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
    val v: View = LayoutInflater.from(parent.context).inflate(R.layout.recyclerview_main_account_item,
            parent, false)
    return MyViewHolder(v)
}

fun deleteItem(position: Int) {
    snapshots.getSnapshot(position).reference.delete()
}

inner class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    var transactionDateTextView: TextView
    var noteTextView: TextView
    var amountTextView: TextView


    init {
        transactionDateTextView = itemView.findViewById(R.id.transactionDateTextView)
        noteTextView = itemView.findViewById(R.id.noteTextView)
        amountTextView = itemView.findViewById(R.id.amountTextView)//



        itemView.setOnClickListener {
            val position = adapterPosition
            if (position != RecyclerView.NO_POSITION && listener != null) {
                listener!!.onItemClick(snapshots.getSnapshot(position), position)
            }
        }
    }
}

interface OnItemClickListener {
    fun onItemClick(documentSnapshot: DocumentSnapshot?, position: Int)
}

fun setOnItemClickListener(listener: OnItemClickListener?) {
    this.listener = listener
}



fun convertLongToDateString(systemTime: Long): kotlin.String {
    //return SimpleDateFormat("dd-MM-yyyy' Time: 'HH:mm")
    return SimpleDateFormat("dd-MM-yyyy")
            .format(systemTime).toString()
}

fun convertIntToCurrencyString(money :Double): kotlin.String {
    //currency formatter
    val formatter: NumberFormat = DecimalFormat("#,###.##")
    val myNumber = money
    val formattedNumber: kotlin.String = formatter.format(myNumber)

    return formattedNumber
    //currency formatter
}

}

标签: androidkotlingoogle-cloud-firestoreandroid-recyclerview

解决方案


因为您使用的FirestoreRecyclerAdapter数据是自动更新的,并且您无法控制它,所以我解释了一些可以帮助您的选项:

在您的适配器类中添加这样的方法:

 fun getAcountBalance():String{
   // iterate and update value of MainAccountBalance
   // add a log to check if your calculated value is correct
   return MainAccountBalance.toString() 
 }

在您使用此适配器的活动或片段中执行此操作(如果您使用片段,请在 onViewCreated 中执行 onCreate 部分):

    override fun onCreate(savedInstanceState: Bundle?) {
    .....
    
    // difine yourTopTextView before this part

    // initialize your adapter
    val yourAdapter = RecyclerViewAdapter(...)
    //add observer to adapter changes 
    yourAdapter.registerAdapterDataObserver(object : 
    RecyclerView.AdapterDataObserver() {
        // setText the view after any change
        
        override fun onChanged() {
            super.onChanged()
            setTextOfYourView(yourAdapter.getAcountBalance())
        }

        override fun onItemRangeChanged(positionStart: Int, itemCount: Int) {
            super.onItemRangeChanged(positionStart, itemCount)
            setTextOfYourView(yourAdapter.getAcountBalance())
        }

        override fun onItemRangeChanged(positionStart: Int, itemCount: Int, payload: Any?) {
            super.onItemRangeChanged(positionStart, itemCount, payload)
            setTextOfYourView(yourAdapter.getAcountBalance())
        }

        override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
            super.onItemRangeInserted(positionStart, itemCount)
            setTextOfYourView(yourAdapter.getAcountBalance())
        }

        override fun onItemRangeRemoved(positionStart: Int, itemCount: Int) {
            super.onItemRangeRemoved(positionStart, itemCount)
            setTextOfYourView(yourAdapter.getAcountBalance())
        }

        override fun onItemRangeMoved(fromPosition: Int, toPosition: Int, itemCount: Int) {
            super.onItemRangeMoved(fromPosition, toPosition, itemCount)
            setTextOfYourView(yourAdapter.getAcountBalance())

        }
    })
    // set adapter to recycler view
    youRecyclerView.adapter= yourAdapter
}

fun  setTextOfYourView(balnce :String){
    yourTopTextView.setText(balnce)
}

推荐阅读