Click here to Skip to main content
15,868,093 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have been working on a stock keeping application as a demo to learn kotlin and android studio, I have added textchangedlistener in a recycler view item, which everytime it text is changed, gets information from Api and displays new item on textview. This works good for only one time, After that it keeps infinitely changing. please check video for better understanding : [ScreenRecording][1] .

Here is my rcv adapter :

Kotlin
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)
    }


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

    }

    fun getUpdatedDetails(skucode:String,pos:Int){
        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 != null) {
                    dataList.removeAt(pos)
                    for (i in skuDetails){
                        println(i.item_name)
                        dataList.add(pos,i)
                    }
                    notifyItemChanged(pos)
                }

            }

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


    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) {
                    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) {
                    var x:String=""
                    var pos:Int=adapterPosition
                        for (i in 0 until RecyclerViewAdapter.ob.dataSelected.size){

                            if (editable.toString().trim()!=""){
                                x=editable.toString().trim()
                                //RecyclerViewAdapter.ob.dataSelected[adapterPosition].sku_code=x
                                println("$x in if")
                            }
                        }
                        //println(RecyclerViewAdapter.ob.dataSelected[adapterPosition].sku_code)
                        //getting edited text and calling the function to get updated details.
                        getUpdatedDetails(x,pos)
        binding.skuStock.removeTextChangedListener(this)

                    }
            })
        }

    }
}


If possible please review my code and let me know what are things i need to work on.
Note: `ob.dataselected` is a global variable from another recyclerview adapter.
Textchangedlistener i am talking about is in the `fun updateStockDetail()`




[1]: https://drive.google.com/file/d/1t_2Gm60q3rero6p9pEUXe-aNGYP192ug/view?usp=sharing

What I have tried:

I have tried using remove text changed listener, and breaking loops. The whole textchanged listener is repeated and not just any part. Please check video link i shared to understand what is happening...
Posted
Updated 8-Feb-22 22:10pm
v2
Comments
David Crow 9-Feb-22 13:40pm    
Have you tried commenting out the call to getUpdatedDetails() in the afterTextChanged() method?
syed ahad 2022 9-Feb-22 13:42pm    
Yes, it works fine if i comment that.
syed ahad 2022 9-Feb-22 13:43pm    
But I need that to reflect the data
David Crow 9-Feb-22 15:10pm    
The afterTextChanged() method is called to notify you that, somewhere within editable, the text has been changed. My suggestion would be to move the call to removeTextChangedListener to the beginning of afterTextChanged().

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900