Lanmonster
Lanmonster

Reputation: 93

RecyclerView not showing data on first load

I am trying to load a list of data from local db using LiveData.

view.xml

... // constraint layout surrounds this
<androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recyclerView_cities"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginEnd="8dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp" />

here is how I am setting up the recycler view in the Fragment:

val citiesAdapter = CitiesAdapter(cityRepository)
with(view.recyclerView_cities) {
    layoutManager = LinearLayoutManager(activity)
    setHasFixedSize(true)
    adapter = citiesAdapter
}
cityRepository.getAllCities().observe(this, Observer { list ->
    citiesAdapter.submitList(list)
})

adapter:

class CitiesAdapter(private val repository: CityRepository) : ListAdapter<City, CitiesAdapter.CardViewHolder>(CityCallback()) {
    class CityCallback: DiffUtil.ItemCallback<City>() {
        override fun areItemsTheSame(oldItem: City, newItem: City): Boolean {
            return oldItem.city == newItem.city && oldItem.stateId == newItem.stateId
        }

        override fun areContentsTheSame(oldItem: City, newItem: City): Boolean {
            return oldItem.city == newItem.city &&
                    oldItem.stateName == newItem.stateName &&
                    oldItem.stateId == newItem.stateId &&
                    oldItem.selected == newItem.selected
        }
    }

    fun getCityAt(position: Int): City = getItem(position)

    // Provide a reference to the views for each data item
    class CardViewHolder(cardView: CardView) : RecyclerView.ViewHolder(cardView) {
        lateinit var checkBox: CheckBox
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CardViewHolder {
        ...
    }

    override fun onBindViewHolder(holder: CardViewHolder, position: Int) {
        ...
    }
}

cityRepository.getAllCities() returns a LiveData> from my database.

I am using the ListAdapter that extends from RecyclerView so that it can handle managing the list for me. Also I am using the DiffUtil so that more granular notifies are called instead of just using notifyDataSetChanged.

Expected Behavior: When I load the fragment, a list is shown in a RecyclerView with all of the cities in the database.

Actual Behavior: When I load the fragment, an empty list is shown even though there are cities in the database. if I add a new city from the fragment, the list is populated with everything that was there before and the newly added item.

EDIT: I hacked in an EditText to the xml and the list populates when I click it from the emulator. It does not work when I try and click it programmatically.

Upvotes: 1

Views: 2436

Answers (3)

Marwa Eltayeb
Marwa Eltayeb

Reputation: 2131

You have two choices to solve this issue.

First, you can set Fixed Size to false.

recyclerView_cities.setHasFixedSize(false)

Second, you can set the minimum height of your RecyclerView to your preferred size in your XML file.

android:minHeight="300dp"

Upvotes: 0

Pachuco Digital
Pachuco Digital

Reputation: 69

You need to attach an observer in the lifecycle

override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        viewModel = ViewModelProviders.of(this, getViewModelFactory()).get(getModelClass())
        attachObservers()
    }

Upvotes: 1

Lanmonster
Lanmonster

Reputation: 93

I removed setHasFixedSize(true) and the data loaded as expected. Can anyone explain why that solved it?

Upvotes: 5

Related Questions