Home > database >  Getting always default values of items from RecycleViewAdapter
Getting always default values of items from RecycleViewAdapter

Time:06-02

I have an activity that has a recycleview. Each item of the recycle view has 3 components: spinner, EditText and an ImageButton

In the activity, there's an "add users" button that should save all the info in the recycleViewer to DB. To give more context, there's also an "add user" button that adds another item to the recycleViewer.

The problem is that when I call the saveUsers function from the activity, who calls the newUserAdapter.getUsers(), that function always returns the list of items of the RecycleView empty (the editText and the Spinner) even if the user has modified the info on the recycleView

Here is my activity


class AddUser : AppCompatActivity() {
    private lateinit var binding: ActivityAddUserBinding
    private lateinit var newUserAdapter : AddUserRecyclerViewAdapter
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityAddUserBinding.inflate(layoutInflater)
        newUserAdapter = AddUserRecyclerViewAdapter()
        val b = User("","")
        newUserAdapter.addItem(b)

        binding.recyclerViewUser.adapter = newUserAdapter
        setContentView(binding.root)
    }

    fun addNewUserRow(view: View) {
        Timber.i("AddUser addNewUserRow called")
        val b = User("","")
        newUserAdapter.addItem(b)
    }


    fun saveUsers(view: View) {
        if(newUserAdapter.itemCount > 0)
        {
            var usr = newUserAdapter.getUsers()
            //TODO: save usr to DataBase
        }
        else
        {
            Snackbar.make(view, R.string.delete_user, Snackbar.LENGTH_LONG).show()
        }
    }
}

This is my User data class:

data class User (
    var name: String = String(),
    var department: String = String()
    )

And my RecycleViewAdapter:

class AddUserRecyclerViewAdapter : RecyclerView.Adapter<AddUserRecyclerViewAdapter.AddUserViewHolder>() {
    private var allUsers = ArrayList<User>()
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AddUserViewHolder {
        Timber.i("User onCreateViewHolder")
        val view = AddUserItemBinding.inflate(
            LayoutInflater.from(parent.context),
            parent,
            false
        )
        val tempUser = AddUserViewHolder(view)
        tempUser.deleteBtn.setOnClickListener {
            Timber.i("NewUser setOnClickListener "   tempUser.bindingAdapterPosition)
            if (this.itemCount > 1)
            {
                deleteItem(tempUser.bindingAdapterPosition)
            }
            else
            {
                //At least one item, we don't let delete the last one
                Snackbar.make(it, R.string.delete_user, Snackbar.LENGTH_LONG).show()
            }
        }

        return tempUser
    }

    override fun onBindViewHolder(holderUser: AddUserViewHolder, position: Int) {
        Timber.i("NewUser onBindViewHolder $position")
        val item = allUsers[position]
        holderUser.nameEt.setText(item.name.toString())

    }

    private fun deleteItem(pos: Int) {
        Timber.i("NewUser deleteItem $pos")
        allUsers.removeAt(pos)
        // call notifyDataSetChanged() to notify our adapter.
        notifyItemRemoved(pos)
    }

    fun addItem(item: User) {
        allUsers.add(item)
        // call notifyDataSetChanged() to notify our adapter.
        notifyItemInserted(allUsers.size -1)
    }

    fun getUsers(): ArrayList<User> {
        return allUsers
    }

    override fun getItemCount(): Int {
        Timber.i("NewUser getItemCount called"   allUsers.size)
        return allUsers.size
    }

    inner class AddUserViewHolder(binding: AddUserItemBinding) :
        RecyclerView.ViewHolder(binding.root) {

        var nameEt: EditText = binding.etName
        var deleteBtn : ImageButton = binding.btnDelete
        var spinnerDepartment : Spinner = binding.spinnerDepartment
    }

}

Edit

As it seems that someone downvoted for lack of information, let me say it in different words. This is the function in RecycleViewAdapter:

 fun getUsers(): ArrayList<User> {
        return allUsers
    }

Who is called when a button is clicked from the activity:

fun saveUsers(view: View) {
        if(newUserAdapter.itemCount > 0)
        {
            var usr = newUserAdapter.getUsers()
            //TODO: save usr to DataBase
        }
        else
        {
            Snackbar.make(view, R.string.delete_user, Snackbar.LENGTH_LONG).show()
        }
    }

So the var usr is where I get a list of empty users, where I expected to get a list of users with the information filled in the RecycleView.

CodePudding user response:

You should update the property of the user in the ArrayList when you are changing the text with an addTextChangedListener

    override fun onBindViewHolder(holderUser: AddUserViewHolder, position: Int) {
        Timber.i("NewUser onBindViewHolder $position")
        val item = allUsers[position]
        holderUser.nameEt.setText(item.name.toString())
        holderUser.nameEt.addTextChangedListener(object : TextWatcher {
            override fun afterTextChanged(p0: Editable?) { }
            override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) { }
            override fun onTextChanged(text: CharSequence?, p1: Int, p2: Int, p3: Int) {
                // Update user instance in allUsers
                allUsers[position].name = text.toString()
            }
        })
    }

You may want also want to define an onItemSelectedListener on the Spinner to update the selected department as well.

  • Related