Reputation: 1
I have an App that is communicating with a meshNetwork and constantly receiving messages over wifi with the properties of meshNodes. Those nodes should be displayed in a RecyclerView
and also updated when a property changes with the usage of LiveData
.
However when I receive multiple messages at almost the same time, the RecyclerView does not update the list.
E.g. a message form a meshNode is received, if the node is not already in a list inside LiveData<List<>>
it will be added. After adding it to the list, the bound recycler view displays the node, everything is perfect by now. Immediatly after a new message from another meshNode that is not in the list is received, and added to the list, the meshNode is not displayed in the RecyclerView.
I really dont know why, and every help will be appreciated.
MeshNodeHandler
handles messages received from meshNetwork, and updating nodes list
class MeshNodeHandler() : MeshHandler.MeshListener() {
private val mMeshNodes= mutableListOf<MeshNode>()
private val mMeshNodesLiveData = MutableLiveData<List<MeshNode>> = MutableLiveData()
val meshNodes: LiveData<List<MeshNode>>= mMeshNodesLiveData
override fun onNodeMessageReceived(nodeMessage: NodeMessage) {
val node =
mMeshNodes.firstOrNull {
it.meshID == nodeMessage.meshID
}
if (node != null && checkIfNodePropertiesChanged(node, nodeMessage)) {
Timber.d("Update mesh node")
// Update node in List...
mMeshNodesLiveData.postValue(mMeshNodes)
} else if (node == null) {
Timber.d("Add mesh node")
// Add node to list
mMeshNodesLiveData.postValue(mMeshNodes)
}
}
}
MeshNodesListViewModel
just exposing the list from the NodeHandler
class MeshNodesListViewModel @Inject constructor(
private val meshNodeHandler: MeshNodeHandler
) : ViewModel() {
val meshNodes: LiveData<List<MeshNode>> = meshNodeHandler.meshNodes
}
And MeshNodesListFragment
that observes the LiveData
and submits the list to the adapter
class MeshNodesListFragment : BaseFragment<FragmentMeshNodesListBinding, MeshNodesListViewModel>(
layoutId = R.layout.fragment_mesh_nodes_list
) {
@Inject
lateinit var viewAdapter: MeshNodesAdapter
override fun onInitDataBinding() {
// DataBinding stuff ...
viewBinding.meshNodesRecyclerView.apply {
adapter = viewAdaper
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel.meshNodes.observe(viewLifecycleOwner, {
Timber.d("Submit list")
viewAdapter.submitList(it)
})
}
}
Logcat:
D/MeshNodeHandler: Add mesh node
D/MeshNodesListFragment: Submit List
...
D/MeshNodehandler: Add mesh node
D/MeshNodesListFragment: Submit List
So the log says that a second node has been added to the LiveData<List<>>
, and the list should also be submitted to the Adaper
, but there is no second item displayed in the RecyclerView
. If I destroy the Fragment
and creating it again by switchig to portrait mode, then both items are displayed.
I'm thankful for every reply, cheers and stay healthy!
Upvotes: 0
Views: 503
Reputation: 1338
I think you are missing the notifyDataSetChanged()
after you update the list. My understanding is that the list is updated but not reflecting in the view because recyclerView is not updating it's views. Try to call notifyItemInserted()
or notifyItemRangeInserted()
variants based on if you are adding single or multiple items. Hope this resolves the issue. Let me know if it helps.
Upvotes: 0