Dominik
Dominik

Reputation: 1345

DiffUtil Recycler view impementation

I created recycler view with data from DB. Call to DB is triggered in mainActivity.

I'm trying to reload recyclerView when an element from DB is deleted.

MainActivity triggers Dialog, callback from Dialog run method to delete user from DB in MainActivity. (deleteBorrower)

I tried to implement DiffUtil, but I don't know how to finish it and where updateBorrowersListItem should be assigned.

class MainActivity : AppCompatActivity() {

    private val db by lazy { Database.getInstance(applicationContext).database }

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

        addDebtBtn.setOnClickListener {
            val intent = Intent(this, AddDebtActivity::class.java)
            intent.putExtra("type", AddDebtActivity.TYPE_NEW)
            startActivity(intent)
        }

        thread {
            var borrowers =
                db.borrowers()
                    .getAll()

            runOnUiThread {
                val debtsSum = borrowers.sumByDouble { it.debt }

                // update sum of debts
                summary.text = debtsSum?.toBigDecimal().setScale(2, 2).toString()

                // update item list
                recycler.apply {
                    layoutManager = LinearLayoutManager(this@MainActivity)
                    adapter = BorrowersListAdapter(borrowers, ::onBorrowerClick, ::onBorrowerLongClick)
                }
            }
        }
    }

    private fun onBorrowerLongClick(borrower: Borrower, position: Int) {
        val dialogDeleteConfirm = DialogDeleteConfirm()

        val bundle = Bundle()
        bundle.putInt("borrowerId", borrower.id)
        bundle.putInt("position", position)
        dialogDeleteConfirm.arguments = bundle

        dialogDeleteConfirm.show(supportFragmentManager, "DeleteDialogConfirm")
    }

    private fun onBorrowerClick(borrower: Borrower) {
        // start edit intent
        val intent = Intent(this, AddDebtActivity::class.java)

        //  add data to edit borrower
        intent.putExtra("type", AddDebtActivity.TYPE_EDIT)
        intent.putExtra("name", borrower.name)
        intent.putExtra("debt", borrower.debt.toString())

        startActivity(intent)
    }

    fun deleteBorrower(id: Int, position: Int) {
        thread {
            db.borrowers()
                .deleteBorrower(id)
        }
    }
}

Adapter:

class BorrowersListVh(view: View): RecyclerView.ViewHolder(view) {
    fun refreshData(borrower: Borrower) {
        itemView.borrowersListName.text = borrower.name
        itemView.borrowersLisDebt.text = borrower.debt.toString()
    }
}

class BorrowersListAdapter(private val dane: List<Borrower>, val onItemClicked: (Borrower) -> Unit, val onItemLongClicked: (Borrower, Int) -> Unit) :  RecyclerView.Adapter<BorrowersListVh>() {
    fun updateBorrowersListItem(borrowers: List<Borrower>) {
        val diffCallback = BorrowersDiffCallback(this.dane, borrowers)

        val diffResult = DiffUtil.calculateDiff(diffCallback)

        diffResult.dispatchUpdatesTo(this)
    }

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

    override fun getItemCount(): Int = dane.size

    override fun onBindViewHolder(holder: BorrowersListVh, position: Int) {
        val borrower: Borrower = dane[position]
        holder.refreshData(borrower)

        holder.itemView.setOnClickListener {
            onItemClicked(borrower)
        }

        holder.itemView.setOnLongClickListener {
            onItemLongClicked(borrower, position)
            true
        }
    }
}

class BorrowersDiffCallback(private val newBorrowers: List<Borrower>, private val oldBorrowers: List<Borrower>): DiffUtil.Callback() {
    override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
        return oldBorrowers.get(oldItemPosition).id == newBorrowers.get(newItemPosition).id;
    }

    override fun getOldListSize(): Int {
        return oldBorrowers.size
    }

    override fun getNewListSize(): Int {
        return newBorrowers.size
    }

    override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
        return oldBorrowers.get(oldItemPosition).equals(newBorrowers.get(newItemPosition));
    }

}

Upvotes: 0

Views: 63

Answers (1)

C&#244;ng Hải
C&#244;ng Hải

Reputation: 5261

Your method has a mistake when you call dispatchUpdatesTo you should update dane too. You should change dane to MutableList instead of List

    fun updateBorrowersListItem(borrowers: List<Borrower>) {
        val diffCallback = BorrowersDiffCallback(this.dane, borrowers)
        val diffResult = DiffUtil.calculateDiff(diffCallback)
        dane.clear()
        dane.addAll(borrowers)
        diffResult.dispatchUpdatesTo(this)
    }

Update code when you call deleteBorrower

    fun deleteBorrower(id: Int, position: Int) {
        thread {
            db.borrowers()
                .deleteBorrower(id)
            var borrowers = db.borrowers().getAll()

            runOnUiThread {
                (recycler.adapter as BorrowersListAdapter).updateBorrowersListItem(borrowers)
            }
        }
    }

Upvotes: 1

Related Questions