I am displaying two fragments in the activity with recyclerViews. I am trying to add a new item to the recycler view but I am getting : "lateinit property remindersViewModel has not been initialized" error. I am already trying to initialise it in the fragments.
My Fragment 1:
import android.content.Intent
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.bubblereminder.room.Reminders
import com.example.bubblereminder.room.RemindersListAdapter
import com.example.bubblereminder.room.RemindersViewModel
class ScheduledFragment : Fragment() {
private lateinit var reminderViewModel: RemindersViewModel
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val v = inflater.inflate(R.layout.fragment_scheduled, container, false)
return v
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
val recyclerView = view?.findViewById<RecyclerView>(R.id.recycler_scheduled)
val adapter = context?.let { RemindersListAdapter(it) }
if (recyclerView != null) {
recyclerView.adapter = adapter
}
if (recyclerView != null) {
recyclerView.layoutManager = LinearLayoutManager(context)
}
this.reminderViewModel = ViewModelProvider(this).get(RemindersViewModel::class.java)
reminderViewModel.allReminders.observe(viewLifecycleOwner, Observer { reminders ->
// Update the cached copy of the words in the adapter.
reminders?.let {
if (adapter != null) {
adapter.setReminders(it)
}
}
})
}
}
My Fragment 2:
package com.example.bubblereminder
import android.content.Intent
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.bubblereminder.room.Reminders
import com.example.bubblereminder.room.RemindersListAdapter
import com.example.bubblereminder.room.RemindersViewModel
class DoneFragment : Fragment() {
private lateinit var reminderViewModel: RemindersViewModel
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val v = inflater.inflate(R.layout.fragment_scheduled, container, false)
return v
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
val recyclerView = view?.findViewById<RecyclerView>(R.id.recycler_scheduled)
val adapter = context?.let { RemindersListAdapter(it) }
if (recyclerView != null) {
recyclerView.adapter = adapter
}
if (recyclerView != null) {
recyclerView.layoutManager = LinearLayoutManager(context)
}
this.reminderViewModel = ViewModelProvider(this).get(RemindersViewModel::class.java)
reminderViewModel.allReminders.observe(viewLifecycleOwner, Observer { reminders ->
// Update the cached copy of the words in the adapter.
reminders?.let {
if (adapter != null) {
adapter.setReminders(it)
}
}
})
}
}
My Activity:
package com.example.bubblereminder
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.FrameLayout
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelProviders
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.bubblereminder.room.Reminders
import com.example.bubblereminder.room.RemindersDao
import com.example.bubblereminder.room.RemindersListAdapter
import com.example.bubblereminder.room.RemindersViewModel
import com.ramotion.circlemenu.CircleMenuView
class MainActivity : AppCompatActivity() {
private lateinit var remindersViewModel: RemindersViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setupMenuEventListener()
setupFragments(R.id.fragment_container1, ScheduledFragment())
setupFragments(R.id.fragment_container2, DoneFragment())
}
private fun setupMenuEventListener() {
val circleMenu = findViewById<CircleMenuView>(R.id.circle_menu)
circleMenu.eventListener = object : CircleMenuView.EventListener() {
override fun onButtonClickAnimationEnd(view: CircleMenuView, index: Int) {
when (index) {
0 -> {
remindersViewModel.insert(Reminders(0,"Sample Reminder Text"))
val confirmToast = "Task 1 Finished"
Toast.makeText(this@MainActivity, confirmToast, Toast.LENGTH_SHORT)
.show()
}
1 -> {
val confirmToast = "Task 2 Finished"
Toast.makeText(this@MainActivity, confirmToast, Toast.LENGTH_SHORT)
.show()
}
2 -> {
val confirmToast = "Task 3 Finished"
Toast.makeText(this@MainActivity, confirmToast, Toast.LENGTH_SHORT)
.show()
}
3 -> {
val confirmToast = "Task 4 Finished"
Toast.makeText(this@MainActivity, confirmToast, Toast.LENGTH_SHORT)
.show()
}
4 -> {
val confirmToast = "Task 5 Finished"
Toast.makeText(this@MainActivity, confirmToast, Toast.LENGTH_SHORT)
.show()
}
}
}
}
}
private fun setupFragments(id:Int , frag:Fragment){
var fragmentManager = supportFragmentManager
fragmentManager.beginTransaction()
.replace(id, frag)
.commit()
}
}
I tried to initialise the view model in the activity but I was not able to.
Each remindersViewModel
variable you have is completely separate, and by marking them as lateinit
you're promising to set a value on them before you try to read them. You're doing that in the fragments, but you're not initialising the one in MainActivity
before you call insert
on it