1

This is the kotlin code where I have a order cart which consists of an ArrayList of elements and what I am trying to do here is that by default there will be quantity set to 1 in the EditText and I have buttons to increment and decrement it. So whenever I try to increment or decrement the value using those buttons the total amount for the TextView in each row must be changed. However now everything is working fine like whenever I increment or decrement the value the TextView total amount changes in a row but when I scroll down or up the value in the TextView disappears and is set back to its default value.

internal class KartListAdapter(private var arrayList: List<Kartdata>,
                           private val context: Context,
                           var presenter: MainContract.Presenter,
                           var recyclerview: RecyclerView,grandtotalTv:TextView) : RecyclerView.Adapter<KartListAdapter.MainHolder>() {

    var list=arrayList

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

    override fun onBindViewHolder(holder: MainHolder, position: Int) {

        holder.bindItem(arrayList[position])
        holder.itemsqty.tag = position
        holder.perpriceprice.tag=position

        var qtyval:Int = holder.itemsqty.text.toString().toInt()
        var perqtyPrice = arrayList[position].qtyPrice

        holder.btnIncrease.setOnClickListener() {
            qtyval++
            holder.itemsqty.text=qtyval.toString()
        }

        holder.btnDecrease.setOnClickListener() {
            qtyval--
            holder.itemsqty.text=qtyval.toString()
        }

        holder.itemsqty.addTextChangedListener(object : TextWatcher {
            override fun afterTextChanged(s: Editable) {
               // Toast.makeText(context,"after text change"+s.toString(),Toast.LENGTH_LONG).show()
            }

            override fun beforeTextChanged(s: CharSequence, start: Int,
                                           count: Int, after: Int) {
                //Toast.makeText(context,"before text change"+s.toString(),Toast.LENGTH_LONG).show()
            }

            override fun onTextChanged(s: CharSequence, start: Int,
                                       before: Int, count: Int) {
                if(s.toString().trim()!="") {
                    if (s.toString().toInt()<1) {
                        val perpiecetotal=qtyval*perqtyPrice
                        holder.itemsqty.text="1"
                        holder.perpriceprice.text="OMR:"+perpiecetotal.toString()

                    } else {
                        val perpiecetotal=qtyval*perqtyPrice
                        Log.i("pricing-qtyval",qtyval.toString())
                        Log.i("pricing-perqtyprice",perqtyPrice.toString())
                        holder.perpriceprice.text="OMR:"+perpiecetotal.toString()
                        Log.i("pricing-grandtotalprice",perpiecetotal.toString())
                        holder.perpriceprice.tag=position
                    }
                    //Toast.makeText(context,"on text change"+s.toString(),Toast.LENGTH_LONG).show()
                } else {
                    Toast.makeText(context,"somewhere qty is empty",Toast.LENGTH_LONG).show()

                }
            }
        })
    }

    override fun getItemViewType(position: Int): Int {
        return position
    }

    override fun getItemCount(): Int {
        return arrayList.size
    }

    internal inner class MainHolder(view: View) : RecyclerView.ViewHolder(view) {

        var menuname = itemView.findViewById<TextView>(R.id.cateegory_tv)
        var qtyname = itemView.findViewById<TextView>(R.id.qty_name)
        var qtyprice = itemView.findViewById<TextView>(R.id.qty_price)
        var perpriceprice = itemView.findViewById<TextView>(R.id.price_calculated_tv_item)
        var itemsqty = itemView.findViewById<TextView>(R.id.no_of_items_edt)
        var deleteicon = itemView.findViewById<ImageView>(R.id.delete_icon)
        var btnIncrease = itemView.findViewById<ImageView>(R.id.btn_increase)
        var btnDecrease = itemView.findViewById<ImageView>(R.id.btn_decrease)

        fun bindItem(kart: Kartdata) {
            menuname.setText(kart.MenuName)
            qtyname.setText(kart.qtyName)
            qtyprice.setText("OMR\t"+kart.qtyPrice)
            val perpiecetotal=1*kart.qtyPrice
            perpriceprice.text="OMR:"+perpiecetotal.toString()

            deleteicon.setOnClickListener() {
                val database = KartDatabase.getInstance(context)
                val repository = KartRepository(AppExecutors(), database.dapendukDAO())
                Toast.makeText(context,"deleted",Toast.LENGTH_SHORT).show()
                presenter.deleteitem(repository,kart.id)
                presenter.getlistsize(repository)
                (context as FragmentActivity).supportFragmentManager.beginTransaction()
                        .disallowAddToBackStack()
                        .replace(R.id.container, KartFragment.newInstance(), KartFragment.TAG)
                        .commit()
            }
        }
    }
}
Reaz Murshed
  • 23,691
  • 13
  • 78
  • 98
Buraq24 Rep
  • 23
  • 1
  • 9

1 Answers1

0

You need to have an array of quantities in the KartListAdapter to save the quantities. The values are disappearing an showing wrongly is because the views are getting recycled in the RecyclerView. So you need to save the sates of each row in a separate ArrayList and then show the quantities from there.

Hence I would like to propose having a separate ArrayList in your KartListAdapter like var quantityList: List<Int>.

Then when a quantity is being increased or decreased, have the value in the quantityList. Initialize this ArrayList with zeros and the size equals to the arrayList passed to the adapter.

Now in your bindView function, set the text in the quantity text field like this.

holder.itemsqty.text = quantityList[position];

And insider onBindViewHolder, while you are updating the quantities, just increase and decrease the values in the quantityList and then call notifyDataSetChanged to make the changes required in your RecyclerView.

holder.btnIncrease.setOnClickListener() {
    quantityList[position] = quantityList[position] + 1;
    notifyDataSetChanged();
}

holder.btnDecrease.setOnClickListener() {
    if(quantityList[position] > 0) { 
        quantityList[position] = quantityList[position] - 1;
        notifyDataSetChanged();
    }
}

The code is not tested and might not work due to syntax errors. However, I think you get the idea of storing the quantities increased or decreased in a separate list and populate the views from there in your RecyclerView.

Hope that helps!

Reaz Murshed
  • 23,691
  • 13
  • 78
  • 98