Home > Net >  How to iterate over items inside a recyclerview adapter get a result and pass it to a fragment
How to iterate over items inside a recyclerview adapter get a result and pass it to a fragment

Time:10-12

Below is my recyclerview adapter, whenever my recyclerview is populated I iterate through all views and calculate total incomes and expenses and get the balance in a variable called MainAccountBalance. how to pass this variable value to my Mainfragment so I can show it on a textview on top of the recyclerview? any time the recyclerview items changes, or the recyclerview populated/repopulated the variable should automatically passed and updated on the textview.

Am new to this, a Kotlin detailed code would really be appreciated. Thanks.

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
}

}

CodePudding user response:

because you are using FirestoreRecyclerAdapter data is updated automatically and you have no control on it, there are some options I explain one of them that can help you :

in your adapter class add a method like this :

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

in your activity or fragment where you are using this adapter do this (if you are using fragment do onCreate part in onViewCreated) :

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