Abdulla
Abdulla

Reputation: 51

Late update for ListView

I have listView that use Realm to populate the items. The list view is a SwipeMenuListView by baoyongzhang. I have an issue that the listView is not being updated instantly. Rather when I exist the app and return back, the list will reflect the new changes.

I use AlertDialog to prompt the users to update selected parameters and those will be updated in the listView.

I use RealmHelper class to populate the listView ArrayAdapter

Below is the code from the helper class (RealmHelper):

fun readAll(): ArrayList<User> {
   val finalList = ArrayList<User>()
   val listOfUsers = mRealm.where(User::class.java).findAll()

   finalList += listOfUsers

   return finalList
}

This is the main activity class code

class Users: AppCompatActivity() {

    private lateinit var realm: Realm

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

        realm = Realm.getDefaultInstance()
        val helper = RealmHelper(realm)
        val users = helper.readAll()
        val mAdapter = MyAdapter(this, users)
        listView.adapter = mAdapter
   }
}

This is the main code where the actual update occurs:

listView.setOnMenuItemClickListener(SwipeMenuListView.OnMenuItemClickListener { position, menu, index ->

            when (index) {
                0 -> {
                    val alert = AlertDialog.Builder(this@Users).create()
                    alert.setTitle("Update Car Details")
                    val all = realm.where(User::class.java).findAll()
                    val selectedCar = all[position]!!
                    val name = EditText(this@Users)
                    name.hint = "Nickname"
                    val carNumber = EditText(this@Users)
                    carNumber.hint = "Car Number"
                    val duration = EditText(this@Users)
                    duration.hint = "Duration (hr)"
                    val code = EditText(this@Emirates)
                    code.hint = "Code"

                    name.setText(selectedCar.nickName)
                    carNumber.setText(selectedCar.plateNum)
                    duration.setText(selectedCar.duration)
                    code.setText(selectedCar.code)

                    val layout = LinearLayout(this)
                    layout.orientation = LinearLayout.VERTICAL
                    layout.addView(name)
                    layout.addView(carNumber)
                    layout.addView(duration)
                    layout.addView(code)

                    alert.setView(layout, 60, 0,60,0)

                    alert.setButton(AlertDialog.BUTTON_POSITIVE,"Update", object :DialogInterface.OnClickListener {
                        override fun onClick(dialog: DialogInterface?, which: Int) {

                            realm.beginTransaction()
                            selectedCar.code = code.text.toString()
                            selectedCar.plateNum = carNumber.text.toString()
                            selectedCar.duration = duration.text.toString()
                            selectedCar.nickName = name.text.toString()
                            emirates[position] = selectedCar
                            realm.commitTransaction()
                            mAdapter.notifyDataSetChanged()
                            Toast.makeText(this@Users, "${mAdapter.notifyDataSetChanged()} called", Toast.LENGTH_LONG).show()

                        }
                    })

                    alert.setButton(AlertDialog.BUTTON_NEGATIVE, "Cancel", object : DialogInterface.OnClickListener {
                        override fun onClick(dialog: DialogInterface?, which: Int) {
                            dialog?.dismiss()
                        }

                    })

                    alert.show()
                }
                1 -> {
                    realm.beginTransaction()
                    val all = realm.where(User::class.java).findAll()
                    val selectedUser = all[position]
                    selectedUser?.deleteFromRealm()
                    emirates.removeAt(position)
                    realm.commitTransaction()
                    mAdapter.notifyDataSetChanged()
                }
                else -> return@OnMenuItemClickListener false
            }

            true
        })

I use Toast to test whether mAdapter.notifyDataSetChanged() is called and I verified that it is called, but seems that listView is not updating until the app is restarted.

Any idea why this behavior is?

Note: this is the link to the actual library of: https://github.com/baoyongzhang/SwipeMenuListView

Upvotes: 0

Views: 43

Answers (1)

The problem with the method notifyDataSetChanged is that it detects when the source of the info changes but not when it is reasigned. I have faced a lot of problems with this method, so what i recomend is not use notifyDateSetChanged in this case but you can create a new adapter with the new source of information. try with this change.

alert.setButton(AlertDialog.BUTTON_POSITIVE,"Update", object :DialogInterface.OnClickListener {
                        override fun onClick(dialog: DialogInterface?, which: Int) {

                            realm.beginTransaction()
                            selectedCar.code = code.text.toString()
                            selectedCar.plateNum = carNumber.text.toString()
                            selectedCar.duration = duration.text.toString()
                            selectedCar.nickName = name.text.toString()
                            emirates[position] = selectedCar
                            realm.commitTransaction()
                            val realm = Realm.getDefaultInstance()
                            val helper = RealmHelper(realm)
                            val users = helper.readAll()
                            mAdapter = MyAdapter(this, users)
                            listView.adapter = mAdapter
                            Toast.makeText(this@Users, "${mAdapter.notifyDataSetChanged()} called", Toast.LENGTH_LONG).show()

                        }
                    })

Try this, i hope it works with you.

Upvotes: 1

Related Questions