I've followed this tutorial: https://developer.android.com/codelabs/android-room-with-a-view-kotlin.
Code works flawlessy, but I wanted to move the RecyclerView to a Fragment. Now the list loads indefinitely and there are no errors in Logcat.
I logged words
in the observe
function.
It logs the Word objects just fine...
I've made some changes in the code when moving to a fragment:
viewModels
-> activityViewModels
application
-> requireActivity().application
owner: this
-> viewLifecycleOwner
All of those didn't help.
This is my code:
MainActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
WordListFragment
class WordListFragment: ListFragment(){
private val wordViewModel: WordViewModel by activityViewModels {
WordViewModelFactory((requireActivity().application as WordsApplication).repository)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
val recyclerView =
inflater.inflate(R.layout.fragment_recycler, container, false) as RecyclerView
val adapter = WordListAdapter()
recyclerView.adapter = adapter
recyclerView.layoutManager = LinearLayoutManager(requireActivity())
wordViewModel.allWords.observe(viewLifecycleOwner) { words ->
words.let { adapter.submitList(it) }
}
return super.onCreateView(inflater, container, savedInstanceState)
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
android:name="com.example.android.roomwordssample.WordListFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
fragment_recycler.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:listitem="@layout/recyclerview_item"
android:padding="@dimen/big_padding"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
The rest is unchanged from original (https://github.com/android/codelab-android-room-with-a-view/archive/kotlin.zip)
You just have to inflate the view in onCreateView and then in onViewCreated start doing anything related to recyclerView.
Here is code for WordListFragment:
package com.example.android.roomwordssample
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.ListFragment
import androidx.fragment.app.activityViewModels
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
class WordListFragment: ListFragment(){
private val wordViewModel: WordViewModel by activityViewModels {
WordViewModelFactory((requireActivity().application as WordsApplication).repository)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_recycler, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
val recyclerView: RecyclerView = view.findViewById(R.id.recyclerview)
val adapter = WordListAdapter()
recyclerView.adapter = adapter
recyclerView.layoutManager = LinearLayoutManager(requireActivity())
wordViewModel.allWords.observe(viewLifecycleOwner) { words ->
words.let { adapter.submitList(it) }
}
}
}