I have a little problem with baseContext in Fragment, in a nutshell, I'm making an application with Retrofit and RecyclerView, and for practice I decided to make them in Fragment,I took this code from MainActivity and then I ran into a problem that I don't know how to replace baseContext in override fun onResponse, I just replaced it with context and it still doesn't work
import androidx.lifecycle.ViewModelProvider
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.myapplicationsadas.*
import kotlinx.android.synthetic.main.fragment_main.*
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
class MainFragment : Fragment() {
lateinit var mService: RetrofitServices
lateinit var layoutManager: LinearLayoutManager
lateinit var adapter: MyMovieAdapter
companion object {
fun newInstance() = MainFragment()
}
private lateinit var viewModel: MainViewModel
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
return inflater.inflate(R.layout.fragment_main, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
viewModel = ViewModelProvider(this).get(MainViewModel::class.java)
mService = Common.retrofitService
recyclerMovieList.setHasFixedSize(true)
//layoutManager = LinearLayoutManager(this, RecyclerView.HORIZONTAL, false)
layoutManager = LinearLayoutManager(context)
recyclerMovieList.layoutManager = layoutManager
getAllMovie()
}
private fun getAllMovie() {
mService.getMovieList().enqueue(object : Callback<MutableList<Movie>>{
override fun onResponse(
call: Call<MutableList<Movie>>,
response: Response<MutableList<Movie>>
) {
adapter = MyMovieAdapter(baseContext, response.body() as MutableList<Movie>)
adapter.notifyDataSetChanged()
recyclerMovieList.adapter = adapter
}
override fun onFailure(call: Call<MutableList<Movie>>, t: Throwable) {
TODO("Not yet implemented")
}
})
}
}
Related
Trying to add an onclicklistener to the items in my recycler view, that will use an intent to open another activity. I've tried finding examples, but I can only find examples using Java or Kotlin examples that aren't using viewbinding.
package com.truuce.anotherrvtest
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.recyclerview.widget.GridLayoutManager
import com.truuce.anotherrvtest.databinding.ActivityHeroBinding
class HeroActivity : AppCompatActivity() {
var binding: ActivityHeroBinding? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityHeroBinding.inflate(layoutInflater)
setContentView(binding?.root)
val adapter = CardAdapter(HeroList.heroList)
binding?.heroRV?.adapter = adapter
binding?.heroRV?.layoutManager = GridLayoutManager(applicationContext, 3)
}
override fun onDestroy() {
super.onDestroy()
binding = null
}
}
package com.truuce.anotherrvtest
import android.content.Context
import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.truuce.anotherrvtest.databinding.HeroCardBinding
class CardAdapter(val heroList: List<Hero>) : RecyclerView.Adapter<CardAdapter.MainViewHolder>() {
inner class MainViewHolder(val heroBinding: HeroCardBinding) :
RecyclerView.ViewHolder(heroBinding.root) {
fun bindHero(hero: Hero){
heroBinding.heroNameTV.text = hero.heroName
heroBinding.heroIV.setImageResource(hero.image)
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MainViewHolder {
return MainViewHolder(HeroCardBinding.inflate(LayoutInflater.from(parent.context), parent, false))
}
override fun onBindViewHolder(holder: MainViewHolder, position: Int) {
val hero = heroList[position]
holder.bindHero(hero)
}
override fun getItemCount() = heroList.size
}
tried adding View.OnClickListener to MainViewHolder, then implemented a member. OnClick(p0: View){}, but no idea how to get it working.
You should add a functional property for a click listener in your adapter.
The Activity can set the item click listener behavior.
class CardAdapter(
val heroList: List<Hero>,
val itemClickListener: (Hero)->Unit
) : RecyclerView.Adapter<CardAdapter.MainViewHolder>() {
inner class MainViewHolder(val heroBinding: HeroCardBinding) :
RecyclerView.ViewHolder(heroBinding.root) {
fun bindHero(hero: Hero) = with(heroBinding) {
heroNameTV.text = hero.heroName
heroIV.setImageResource(hero.image)
root.setOnClickListener { itemClickListener(hero) }
}
}
//...
}
// In Activity:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityHeroBinding.inflate(layoutInflater)
setContentView(binding?.root)
val adapter = CardAdapter(HeroList.heroList) { hero ->
// do something with hero item when it's clicked
}
binding?.heroRV?.adapter = adapter
binding?.heroRV?.layoutManager = GridLayoutManager(applicationContext, 3)
}
I want to use notification on Fragment. And if I touch button, notification will appear.
I use many ways, and I find one way to use it. but it is not worked. only run like this
2022-06-08 15:30:10.765 28876-28876/com.ebookfrenzy.sample D/MyFragment: startMyService: Intent: Intent { cmp=com.ebookfrenzy.sample/.ui.MyService }
And below one is mainFragment.kt
package com.ebookfrenzy.sample.ui.main
import android.content.Intent
import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.ebookfrenzy.sample.databinding.FragmentMainBinding
import com.ebookfrenzy.sample.ui.MyService
class MainFragment : Fragment() {
private var _binding: FragmentMainBinding? = null
private val binding get() = _binding!!
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
companion object {
fun newInstance() = MainFragment()
private const val TAG = "MyFragment"
}
private lateinit var viewModel: MainViewModel
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentMainBinding.inflate(inflater, container, false)
binding.button.setOnClickListener { startMyService()
}
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
private fun startMyService() {
Intent(context, MyService::class.java).also {
Log.d(TAG, "startMyService: Intent: $it")
// Check Android Policy
context?.startForegroundService(it)
// Less than Android Oreo
context?.startService(it)
}
}
}
MyService
package com.ebookfrenzy.sample.ui
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.Service
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.IBinder
import androidx.annotation.Nullable
import androidx.core.app.NotificationCompat
import com.ebookfrenzy.sample.BuildConfig
import com.ebookfrenzy.sample.R
class MyService : Service() {
companion object {
private const val TAG = "MyService"
}
private val FOREGROUND_ID: Int = 290348
private val foregroundNotificationBuilder: NotificationCompat.Builder
get() = NotificationCompat.Builder(this, applicationContext.packageName).
setSmallIcon(R.mipmap.ic_launcher_round).
setContentTitle("title").
setContentText("content text").
setPriority(NotificationCompat.PRIORITY_HIGH)
override fun onCreate() {
super.onCreate()
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
startForegroundService()
return START_STICKY
}
#Nullable
override fun onBind(p0: Intent?): IBinder? {
return null
}
override fun onDestroy() {
super.onDestroy()
stopForeground(true)
}
private fun createNotificationChannel() {
val channelId = applicationContext.packageName
val channelName = BuildConfig.APPLICATION_ID
val channel = NotificationChannel(
channelId, channelName, NotificationManager.IMPORTANCE_DEFAULT
)
val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
manager.createNotificationChannel(channel)
}
private fun startForegroundService() {
val notification = foregroundNotificationBuilder.build()
// when Over android oreo, need to notification channel.
createNotificationChannel()
startForeground(FOREGROUND_ID, notification)
}
}
And other codes are not corrected after created
I want to resolve this problem. Please help me...
I have this code for my layout with RecyclerView
package com.josue.snapshots
import android.content.Context
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.firebase.ui.database.FirebaseRecyclerAdapter
import com.firebase.ui.database.FirebaseRecyclerOptions
import com.google.firebase.database.DatabaseError
import com.google.firebase.database.FirebaseDatabase
import com.josueproyects.snapshots.databinding.FragmentHomeBinding
import com.josueproyects.snapshots.databinding.ItemSnapshotBinding
import com.josueproyects.snapshots.snapshot.Snapshot
class HomeFragment : Fragment() {
private lateinit var mBinding: FragmentHomeBinding
private lateinit var mFirebaseAdapter: FirebaseRecyclerAdapter<Snapshot,SnapshotHoler>
private lateinit var mLayoutManager: RecyclerView.LayoutManager
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
mBinding = FragmentHomeBinding.inflate(inflater,container,false)
return mBinding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val query = FirebaseDatabase.getInstance().reference //es la raiz
.child("snapshot") //es la rama
val options = FirebaseRecyclerOptions.Builder<Snapshot>()
.setQuery(query,Snapshot::class.java).build()
mFirebaseAdapter = object : FirebaseRecyclerAdapter<Snapshot,SnapshotHoler>(options){
private lateinit var mContext: Context
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SnapshotHoler {
mContext = parent.context //declarar el contexto
val view = LayoutInflater.from(mContext)
.inflate(R.layout.item_snapshot,parent,false)
return SnapshotHoler(view)
}
override fun onBindViewHolder(holder: SnapshotHoler, position: Int, model: Snapshot) {
val snapshot = getItem(position)
with(holder){
setListener(snapshot)
with(binding){
tvTitle.text = snapshot.title
Glide.with(mContext)
.load(snapshot.photoUrl)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.centerCrop()
.into(imgPhoto)
}
}
}
override fun onDataChanged() {
super.onDataChanged()
mBinding.progressBar.visibility = View.GONE
}
override fun onError(error: DatabaseError) {
super.onError(error)
Toast.makeText(mContext, error.message,Toast.LENGTH_LONG).show()
}
}
mLayoutManager = LinearLayoutManager(context) //el tipo de vista que se vera (sera de forma LinearLayout)
mBinding.recyclerView.apply {
setHasFixedSize(true)
layoutManager = mLayoutManager
adapter = mFirebaseAdapter
}
}
override fun onStart() {
super.onStart()
mFirebaseAdapter.startListening()
}
override fun onStop() {
super.onStop()
mFirebaseAdapter.stopListening()
}
//holder del snapshot (para el recycler view)
inner class SnapshotHoler(view: View) : RecyclerView.ViewHolder(view){
val binding = ItemSnapshotBinding.bind(view)
fun setListener(snapshot: Snapshot){
}
}
}
But it shows me this error:
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionSnapshotHoler{15a1686 position=1 id=-1, oldPos=0, pLpos:0 scrap [attachedScrap] tmpDetached no parent} androidx.recyclerview.widget.RecyclerView{123fd4a VFED..... .......D 0,0-1080,1437 #7f080163 app:id/recyclerView}, adapter:com.josueproyects.snapshots.HomeFragment$onViewCreated$1#4bb94bb, layout:androidx.recyclerview.widget.LinearLayoutManager#ed17dd8, context:com.josue.snapshots.MainActivity#9d9a2fd
at androidx.recyclerview.widget.RecyclerView$Recycler.validateViewHolderForOffsetPosition(RecyclerView.java:6156)
at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6339)
at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6300)
at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6296)
at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2330)
at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1631)
at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1591)
at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:668)
at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep1(RecyclerView.java:4255)
at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:4010)
at androidx.recyclerview.widget.RecyclerView.consumePendingUpdateOperations(RecyclerView.java:2028)
at androidx.recyclerview.widget.RecyclerView$1.run(RecyclerView.java:417)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:949)
at android.view.Choreographer.doCallbacks(Choreographer.java:761)
at android.view.Choreographer.doFrame(Choreographer.java:693)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:935)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
The project consists of uploading data to Firebase, when I enter the app everything goes well, but when I am in the Add frangment, I click an ImageButton to open the phone gallery, I select the photo and show it, but when show it in the layout I get the error, I know it has to do with the RecyclerView but... What do I do?.
I am following this tutorial about how to make a Tinder like app with Kotlin and using the third library CardStackView :
https://www.simplifiedcoding.net/tinder-like-swipe-cards-android/
However ,in my case ,shows up an error as follow:
Attempt to invoke virtual method 'void com.yuyakaido.android.cardstackview.CardStackView.setLayoutManager(androidx.recyclerview.widget.RecyclerView$LayoutManager)' on a null object reference
at com.gearsrun.stackviewapplication.UI.Home.HomePageFragment.onCreateView(HomePageFragment.kt:36)
HomeUserAdapter.kt:
package com.gearsrun.stackviewapplication.HomeUserClass
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.gearsrun.stackviewapplication.R
import com.squareup.picasso.Picasso
import kotlinx.android.synthetic.main.user_card.view.*
class HomeUserAdapter:RecyclerView.Adapter<HomeUserAdapter.HomeUserViewHolder>() {
private var homeUserList:List<HomeUserItem>?=null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HomeUserViewHolder {
val itemView = LayoutInflater.from(parent.context).inflate(R.layout.user_card,parent,false)
return HomeUserViewHolder(itemView)
}
override fun onBindViewHolder(holder: HomeUserViewHolder, position: Int) {
val homeUserList = generateUser()
val currentItem = homeUserList[position]
Picasso.get().load(currentItem.user_img).into(holder.user_img)
holder.user_name.text = currentItem.user_name
holder.medal_num.text = currentItem.medal_num
holder.id_num.text = currentItem.userId
holder.user_intro.text = currentItem.user_intro
holder.user_give_num.text = currentItem.user_give_num
holder.user_receive_num.text = currentItem.user_receive_num
}
private fun generateUser(): ArrayList<HomeUserItem> {
val list = ArrayList<HomeUserItem>()
list.add(
HomeUserItem(
"https://i.pinimg.com/236x/8c/64/03/8c6403cc892231f15a6845e00d7433a9.jpg",
"Maria",
"200",
"510uu",
"I am from USA ,I am an engineer ,I hope to make the world a better place",
"500",
"100")
)
)
return list
}
override fun getItemCount(): Int {
return homeUserList!!.size
}
class HomeUserViewHolder(itemView: View):RecyclerView.ViewHolder(itemView) {
val user_img : ImageView = itemView.user_img
val user_name : TextView = itemView.user_name
val medal_num : TextView = itemView.medal_num
val id_num : TextView = itemView.id_num
val user_intro : TextView = itemView.user_intro
val user_give_num : TextView = itemView.user_give_num
val user_receive_num : TextView = itemView.user_receive_num
}
}
HomePageFragment.kt
package com.gearsrun.stackviewapplication.UI.Home
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.LinearInterpolator
import androidx.recyclerview.widget.DefaultItemAnimator
import com.gearsrun.stackviewapplication.HomeUserClass.HomeUserAdapter
import com.gearsrun.stackviewapplication.HomeUserClass.HomeUserItem
import com.gearsrun.stackviewapplication.R
import com.yuyakaido.android.cardstackview.CardStackLayoutManager
import com.yuyakaido.android.cardstackview.CardStackListener
import com.yuyakaido.android.cardstackview.Direction
import com.yuyakaido.android.cardstackview.SwipeableMethod
import kotlinx.android.synthetic.main.fragment_home_page.*
class HomePageFragment : Fragment(),CardStackListener {
private lateinit var layoutManager: CardStackLayoutManager
private val adapter = HomeUserAdapter()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val v = inflater.inflate(R.layout.fragment_home_page, container, false)
// v.rv_UserHome.layoutManager = LinearLayoutManager(context,LinearLayoutManager.VERTICAL,false)
layoutManager = CardStackLayoutManager(context,this).apply {
setSwipeableMethod(SwipeableMethod.AutomaticAndManual)
setOverlayInterpolator(LinearInterpolator())
}
stack_view.layoutManager = layoutManager
stack_view.adapter = adapter
stack_view.itemAnimator.apply {
if(this is DefaultItemAnimator){
supportsChangeAnimations = false
}
}
return v
}
override fun onCardDragging(direction: Direction?, ratio: Float) {
TODO("Not yet implemented")
}
override fun onCardSwiped(direction: Direction?) {
TODO("Not yet implemented")
}
override fun onCardRewound() {
TODO("Not yet implemented")
}
override fun onCardCanceled() {
TODO("Not yet implemented")
}
override fun onCardAppeared(view: View?, position: Int) {
TODO("Not yet implemented")
}
override fun onCardDisappeared(view: View?, position: Int) {
TODO("Not yet implemented")
}
}
Could you please help me take a look my code ?
Thank you so much in advance !
Move all that layoutManager and stackView stuff from onCreate to onViewCreated because during onCreate your view is not created yet and same is assured in onViewCreated.
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
layoutManager = CardStackLayoutManager(context,this).apply {
setSwipeableMethod(SwipeableMethod.AutomaticAndManual)
setOverlayInterpolator(LinearInterpolator())
}
stack_view.layoutManager = layoutManager
stack_view.adapter = adapter
stack_view.itemAnimator.apply {
if(this is DefaultItemAnimator){
supportsChangeAnimations = false
}
}
}
or you can refer here
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
Thanks, worked when I initialised it in OnCreate of the MainActivity :
this.remindersViewModel = ViewModelProvider(this).get(RemindersViewModel::class.java)