Mark Scheer
Mark Scheer

Reputation: 117

EditText values in RecyclerView change when items added to RecyclerView

I have a RecyclerView that contains a list of views with EditText fields in them.

I want to be able to change the value in the EditTexts and have that update my dataset. I seem to be accomplishing this but when I add a new item to the list, the values in the EditTexts get mixed up.

I cannot find why this is happening. Any thoughts?

Main Activity

class MainActivity : AppCompatActivity() {
    private lateinit var recyclerView: RecyclerView
    private lateinit var viewAdapter: RecyclerView.Adapter<*>
    private lateinit var viewManager: RecyclerView.LayoutManager

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val myDataSet = ArrayList<Person>()
        myDataSet.add(Person("Tommy"))
        myDataSet.add(Person("John"))
        myDataSet.add(Person("Suzie"))
        myDataSet.add(Person("Leslie"))

        viewManager = LinearLayoutManager(this)
        viewAdapter = PersonAdapter(myDataSet)

        recyclerView = findViewById<RecyclerView>(R.id.rvPersons).apply {
            setHasFixedSize(true)

            layoutManager = viewManager
            adapter = viewAdapter
        }

        val button = findViewById<Button>(R.id.myButton)

        button.setOnClickListener {
            myDataSet.add(Person("new person"))
            myDataSet.forEach {person ->
                Log.i("my-tag", person.name)
            }
            rvPersons.adapter?.notifyDataSetChanged()
        }
    }
}

People Adapter

class PersonAdapter(private val myDataSet: ArrayList<Person>) :
    RecyclerView.Adapter<PersonAdapter.MyViewHolder>() {

    class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        val editText: EditText = view.my_edittext
        var textView: TextView = view.my_textView
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        return MyViewHolder(
            LayoutInflater.from(parent.context)
                .inflate(R.layout.item_person, parent, false)
        )
    }

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        holder.editText.setText(myDataSet[position].name)
        holder.editText.doAfterTextChanged { text ->
            if (!text.isNullOrBlank()) {
                myDataSet[position].name = text.toString()
            }
        }
        holder.textView.text = myDataSet[position].name
    }

    override fun getItemCount(): Int = myDataSet.size
}

Upvotes: 2

Views: 5145

Answers (3)

RahulGunani
RahulGunani

Reputation: 81

For Recycler view Recycle issues :- Add This

@Override
public int getItemViewType(int position) {
    return position;
}

@Override
public long getItemId(int position) {
    return position;
}

Upvotes: 7

Niral Dhameliya
Niral Dhameliya

Reputation: 219

You have to call this.notifyDataSetChanged(); after adding new text into editText.

Upvotes: 0

ardget
ardget

Reputation: 2651

Since old TextWachers are all left registered over onBindViewHolder calls, data is to be broken. Retain the reference to the TextWatcher in MyViewHolder and remove it first in onBindViewHolder().

class PersonAdapter(private val myDataSet: ArrayList<Person>) :
    RecyclerView.Adapter<PersonAdapter.MyViewHolder>() {

    class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) {

        val editText: EditText = view.my_edittext
        var textView: TextView = view.my_textView
        var watcher: TextWatcher? = null
    }

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

        holder.editText.removeTextChangedListener(holder.watcher)

        holder.editText.setText(myDataSet[position].name)
        holder.watcher = holder.editText.doAfterTextChanged { text ->
            if (!text.isNullOrBlank()) {
                myDataSet[position].name = text.toString()
            }
        }
        holder.textView.text = myDataSet[position].name
    }
    
    :
}

Upvotes: 4

Related Questions