Can somebody review my RecyclerView adapter? Text watcher crashes after 4-5 changes in text

242 Views Asked by At

My textchanged listener is for updatestockdetail() is working very weirdly, it crashes after 4-5 times changing the text and it also shows the first item when i change the text for the third time. I believe i am ding something majorly wrong. If somebody could help me, would be very glad.

class RecyclerViewAdapterU (val dataList:ArrayList<ModelClass>): RecyclerView.Adapter<RecyclerViewAdapterU.ViewHolder>() {
    var _binding: UploadItemViewBinding? = null
    val binding get() = _binding!!


        override fun onCreateViewHolder(
        parent: ViewGroup,
        viewType: Int
    ): RecyclerViewAdapterU.ViewHolder {

        val v =
            LayoutInflater.from(parent.context).inflate(R.layout.upload_item_view, parent, false)
        _binding = UploadItemViewBinding.bind(v)

        return ViewHolder(binding.root)
    }

    fun getUpdatedDetails(skucode:String,pos:Int){
       // val skuDetails:ArrayList<ModelClass>
        val call: Call<List<ModelClass>>? =
            ApiClient.instance?.myApi?.getfromsku(skucode)!!
        call!!.enqueue(object : Callback<List<ModelClass>?> {
            override fun onResponse(
                call: Call<List<ModelClass>?>,
                response: Response<List<ModelClass>?>
            ) {
                val skuDetails=response.body()
                if (!skuDetails.isNullOrEmpty()) {
                    val x=dataList[pos].sku_code
                    for (i in skuDetails.indices){
                        println(skuDetails[i].sku_code)
                        println(".........$pos")
                        if (skuDetails[i].sku_code!=x){
                            dataList.removeAt(pos)
                            dataList.add(pos,skuDetails[i])
                            notifyItemChanged(pos)
                        }
                    }
                }


            }

            override fun onFailure(call: Call<List<ModelClass>?>, t: Throwable) {
            }
        })

    }

    override fun onBindViewHolder(holder: ViewHolder, @SuppressLint("RecyclerView") position: Int) {


        bindItems(dataList[position])
        holder.getStock()
      holder.updateStockDetail()

    }
    fun bindItems(data: ModelClass) {

        binding.apply {
            itemquant.text=data.item_quant
            uploadItemName.text = data.item_name
            uploadMfg.text = data.mfg
            skuStock.setText(data.item_stock.toString())
             skuCode.setText(data.sku_code)
        }


    }



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


    inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {


        fun getStock() {



            binding.skuStock.addTextChangedListener(object : TextWatcher {
                override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}
                override fun onTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}
                override fun afterTextChanged(editable: Editable) {
                    if (binding.skuStock.isFocused){
                    for (i in 0 until RecyclerViewAdapter.ob.dataSelected.size){
                        if (editable.toString().trim()!=""){
                            var x= editable.toString().trim().toInt()

                            RecyclerViewAdapter.ob.dataSelected[adapterPosition].item_stock=x
                            //getting current itemstock before pushing update.
                            //assigning latest itemstock to the data for the update
                        }
                    }
                }}

            })
        }

        fun updateStockDetail(){
            binding.skuCode.addTextChangedListener(object : TextWatcher{
                override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}
                override fun onTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {
                }
                override fun afterTextChanged(editable: Editable) {
                    binding.skuCode.removeTextChangedListener(this)
                    var pos:Int=adapterPosition
                    var x= editable.toString().trim()


                    //RecyclerViewAdapter.ob.dataSelected[adapterPosition].sku_code=x
                    println("$x in textwatcher and $pos")

                    //getting edited text and calling the function to get updated details.

                    getUpdatedDetails(x,pos)
                   binding.skuCode.addTextChangedListener(this)

                }
            })

        }

    }
}

Before anyone asks, ob.dataselected comes from another rcv adapter. There is a issue in notifyitemchanged(pos) in getupdateddetails() which is called from updateStockDetail().

1

There are 1 best solutions below

3
harun karaca On
binding.skuCode.addTextChangedListener(this)

above code is causing the loop. You have to get rid of this line.