I am making an app that is composed of a single activity.
The user can create an array of predefined size by clicking a button. And with an other button, I want the array to be sorted using various algorithms.
The algorithm and their performance time are displayed in a ListView
. See the screenshot below as an example:
My listView
is created like this in MainActivity
:
listView.adapter = MyCustomAdapter(this)
and below is the adpter code:
class MyCustomAdapter(context: Context): BaseAdapter() {
private val mContext: Context = context
val names = MainActivityViewModel().allAlgorithms
override fun getCount(): Int {
return names.size
}
override fun getItem(p0: Int): Any {
return names[p0]
}
override fun getItemId(p0: Int): Long {
return p0.toLong()
}
override fun getView(p0: Int, p1: View?, p2: ViewGroup?): View {
val layoutInflater = LayoutInflater.from(mContext)
val row = layoutInflater.inflate(R.layout.row_algorithm, p2, false)
val nameTextView = row.findViewById<TextView>(R.id.algoName)
nameTextView.text = names[p0].name
val timer = row.findViewById<TextView>(R.id.timer)
timer.text = names[p0].time
return row
}
}
allAlgorithms
that comes from my ViewModel
is a MutableList<Algorithm>
.
The Algorithm class:
class Algorithm(var name: String, var time: String = "0.00 sec")
For the moment this MutableList<Algorithm>
is initialized using a listOf(various algo names)
. This means that the time is kept to default value.
Now when the user clicks the start benchmark button, this function is called in my ViewModel
:
private var _executionTime = MutableLiveData<Long>(timer)
val executionTime: LiveData<Long>
get() = _executionTime
private var _index = MutableLiveData(0)
val index: LiveData<Int>
get() = _index
fun startBench() {
for ((i,v) in names.withIndex()) {
_executionTime.value = measureTimeMillis {
arr.sort() // is the arr generated by clicking the button
}
_index.value = i
}
}
I will make different functions for each algorithms later, but for now I want my ListView
to be updated to my executionTime.value()
for the right algorithm.
I have tried to put an observer inside my adapter, but I cannot get a ViewModelProvider
since I did not find a way to access a LifeCycleOwner.
I also have tried to update my allAlgorithm
list but of course it doesn't update the UI.
MY QUESTIONS:
I was doing a pretty obvious mistake that was causing my notifyDataSetChanged() not to work:
In MyCustomAdapter
instead of passing the original version of the MainActivityViewModel
, I was instanciating new viewModel
every call which is not smart.
The easy fix was to pass my instance of MainActivityViewModel
to the adapter like this:
val adapter = MyCustomAdapter(this, viewModel)
listView.adapter = adapter
And mofify the adapter accordingly:
class MyCustomAdapter(context: Context, vm: MainActivityViewModel): BaseAdapter()
and the changes were taken into account.