I have a ListView and trying to use two-way data binding to set the selectedItemPosition in a ViewModel using Two-Way Attributes
But the problem is it doesn't work, the selected item doesn't set in the Value of the liveData, I tried to observe it and the value never changes when i select an item in the listView
data binding in XML:
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="@dimen/_150sdp"
android:nestedScrollingEnabled="true"
tools:listheader="@tools:sample/lorem"
tools:visibility="visible"
android:choiceMode="singleChoice"
android:selectedItemPosition="@={viewModel.chosenPosition}" />
in the ViewModel:
val chosenPosition = MutableLiveData<Int>()
in the Fragment:
binding.viewModel = viewModel
binding.lifecycleOwner = viewLifecycleOwner
binding.teamsListView.adapter = ArrayAdapter(
context,
R.layout.list_item_choice, teamsNames
)
viewModel.chosenPosition.observe(viewLifecycleOwner) {
Timber.d("chosen position = $it") //never triggers when I select an item in the ListView
}
Problem:
android:selectedItemPositionis triggered whenever an item is selected (this doesn't implicitly include that the item is clicked/checked.Using
android:selectedItemPositionas a two-way data binding in aListViewdoesn't actually automatically triggered when an item is selected, and therefore the LiveData doesn't get triggered.You can see that when you create a normal
ListViewwithout any data binding; when you click an item, this won't trigger the selection, notice the below when an item is clicked (nothing get highlighted with a different color):Solution:
In order to solve that for the sake of data binding, you need to explicitly do select the that item whenever it is clicked by registering
OnItemClickListenerto theListView:This way the live data will be set to the current selected position:
Notice when an item is selected, it's now highlighted with a light grey that is because the selection is enabled: