blackst0ne
blackst0ne

Reputation: 3264

Room Database entries in RecyclerView

I want to show Room Database entries in a RecyclerView. So far I have the Room skeleton and I can show some dummy content (not from Room) in the RecyclerView:

enter image description here

However I have struggles showing Room DB entries instead of the dummy content. In Arduino the EEPROM I/O stuff used to be almost a oneliner but within Android Room this conceptually easy task seems to be a code-intense and not-so-forward challenge. This brings me to my first question:

1) As in my case the database is pretty slim and simple, is there any simpler approach than Room using less overhead and classes?

Regarding the Room approach, I believe that I am pretty close. I have difficulties implementing the following:

2) How can I substitute the for-loop in init DummyContent by the Room-DB entries (allJumps from ViewModel)?

Here is what I got so far (I didn't post anything below the ViewModel such as Repository and DAO's as it should not of interest right now):

DummyItems (dummy contents to be replaced by Room DB entries)

object DummyContent {

    // An array of sample (dummy) items.
    val ITEMS: MutableList<DummyItem> = ArrayList()

    // A map of sample (dummy) items, by ID.
    val ITEM_MAP: MutableMap<String, DummyItem> = HashMap()

    private val COUNT = 25

    init {
        // Add some sample items.
        // TO BE REPLACED BY ROOM DB ENTRIES <----------------------------------------------------
        for (i in 1..COUNT) {
            addItem(createDummyItem(i))
        }
    }

    private fun addItem(item: DummyItem) {
        ITEMS.add(item)
        ITEM_MAP.put(item.id, item)
    }

    private fun createDummyItem(position: Int): DummyItem {
        return DummyItem(position.toString(), "Item " + position, makeDetails(position))
    }

    private fun makeDetails(position: Int): String {
        val builder = StringBuilder()
        builder.append("Details about Item: ").append(position)
        for (i in 0..position - 1) {
            builder.append("\nMore details information here.")
        }
        return builder.toString()
    }

    // A dummy item representing a piece of content.
    data class DummyItem(val id: String, val content: String, val details: String) {
        override fun toString(): String = content
    }
}

allJumps / JumpData

// allJumps is of type LiveData<List<JumpData>>

@Entity
data class JumpData (
    @PrimaryKey var jumpNumber: Int,
    var location: String?
}

ViewModel

class JumpViewModel(application: Application) : AndroidViewModel(application) {

    // The ViewModel maintains a reference to the repository to get data.
    private val repository: JumpRepository
    // LiveData gives us updated words when they change.
    val allJumps: LiveData<List<JumpData>>

    init {
        // Gets reference to WordDao from WordRoomDatabase to construct
        // the correct WordRepository.
        val jumpsDao = JumpRoomDatabase.getDatabase(application, viewModelScope).jumpDao()
        repository = JumpRepository(jumpsDao)
        allJumps = repository.allJumps // OF INTEREST <----------------------------------------------------
    }

    fun insert(jump: JumpData) = viewModelScope.launch {
        repository.insert(jump)
    }

    fun getJumps() : LiveData<List<JumpData>> {
        return allJumps
    }
}

Upvotes: 0

Views: 2285

Answers (1)

Mykhailo Plotnikov
Mykhailo Plotnikov

Reputation: 108

You can try to add this to object DummyContent

object DummyContent {
    val jumpsLiveData = MutableLiveData<List<JumpData>>()

    private val observedLiveData: LiveData<List<JumpData>>? = null
    private val dataObserver = object : Observer<List<JumpData>> {
        override fun onChanged(newList: List<JumpData>) {
            // Do something with new data set
        }
    }
    fun observeJumpsData(jumpsLiveData: LiveData<List<JumpData>>) {
        observedLiveData?.removeObserver(dataObserver)
        observedLiveData = jumpsLiveData.apply { 
            observeForever(dataObserver)
        }
    }
}

And this to viewModel's init block:

init {
        val jumpsDao = JumpRoomDatabase.getDatabase(application, viewModelScope).jumpDao()
        repository = JumpRepository(jumpsDao)
        allJumps = repository.allJumps
        DummyContent.observeJumpsData(getJumps())
    }

By this code, DummyContent will automatically subscribe to new data after ViewModel creation

And in 'Activity', where you created RecyclerView, add this text to end of onCreate:

override fun onCreate(savedState: Bundle?) {
  DummyContent.jumpsLiveData.observe(this, Observer {
    recyclerAdapter.changeItemsList(it)
  }
}

changeItemsList - method that changes your recycler's data, i believe, you already created it

Upvotes: 1

Related Questions