'RecyclerView items aren't displayed

I have configured a regular RecyclerView with ListAdapter and DiffUtil. But this time it isn't working. List of items is sucessfully received (which can be checked using Log.d in DriverDetailsFragment) and passed to RecyclerView adapter, but for some reason list isn't displayed.

Fragment - DriverDetailsFragment

class DriverDetailsFragment: Fragment() {
    private var _binding: FragmentDriverDetailsBinding? = null
    private val binding get() = _binding!!

    private lateinit var adapter: LocationsAdapter

    private val viewModel: DriverDetailsViewModel by viewModels {
        DriverDetailsViewModelFactory()
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = DataBindingUtil.inflate(inflater, R.layout.fragment_driver_details, container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        //pass driver id from [arguments] to [viewModel]
        arguments?.let {
            viewModel.setDriverId(
                DriverDetailsFragmentArgs.fromBundle(it).driverId
            )
        }

        binding.viewModel = viewModel

        //configure list
        adapter = LocationsAdapter { location ->
            navToMaps(location.latitude, location.longitude)
        }
        binding.locationList.adapter = adapter

        setObservers()
    }

    private fun setObservers() {
        viewModel.locationList.observe(viewLifecycleOwner) { locationList ->
            val tempList = Helper.sortLocationListByTimestamp(locationList)
            Log.d(TAG, "DriverDetailsFragment: locationList update: $tempList")
            adapter.submitList(
                tempList
            )
        }
    }
}

Adapter - LocationsAdapter

class LocationsAdapter(private val onItemClicked: (Location) -> Unit) :
    ListAdapter<Location, LocationsAdapter.LocationViewHolder>(LocationsDiffCallback()){

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): LocationViewHolder {
        Log.d(TAG, "onCreateViewHolder: onCreate")
        val viewHolder = LocationViewHolder.from(parent)
        viewHolder.itemView.setOnClickListener {
            onItemClicked(getItem(viewHolder.adapterPosition))
        }

        return viewHolder
    }

    override fun onBindViewHolder(holder: LocationViewHolder, position: Int) {
        Log.d(TAG, "onBindViewHolder: onBind")
        val item = getItem(position)
        holder.bind(item)
    }

    class LocationViewHolder
    private constructor(private val binding: ListItemLocationBinding) :
        RecyclerView.ViewHolder(binding.root) {

        fun bind(location: Location) {
            binding.coordinates.text =
                String.format(location.latitude + ", " + location.longitude)
            binding.timestamp.text = Helper.timestampToDate(location.timestamp)
        }

        companion object {
            fun from(parent: ViewGroup): LocationViewHolder {
                val layoutInflater = LayoutInflater.from(parent.context)
                val binding = ListItemLocationBinding.inflate(layoutInflater, parent, false)
                return LocationViewHolder(binding)
            }
        }
    }
}

class LocationsDiffCallback : DiffUtil.ItemCallback<Location>() {
    override fun areItemsTheSame(oldItem: Location, newItem: Location): Boolean {
        return oldItem.timestamp == newItem.timestamp
    }

    override fun areContentsTheSame(oldItem: Location, newItem: Location): Boolean {
        Log.d(TAG, "areContentsTheSame: ${oldItem == newItem}")
        return oldItem == newItem
    }

}

XML - fragment_driver_details

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>
        <variable
            name="viewModel"
            type="com.slovo.drive.viewmodel.DriverDetailsViewModel" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/location_list"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:paddingBottom="8dp"
            android:paddingEnd="8dp"
            android:clipToPadding="false"
            tools:ignore="RtlSymmetry"
            app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"/>
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

With help of Log.d checked each stage in fragment and adapter. Logs from Adapter aren't displayed for some reason. But everything else seems to be okay.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source