简体   繁体   English

无法在 RecyclerView.Adapter 类 Kotlin 中获取 ViewModel 实例

[英]Unable to get ViewModel instance in RecyclerView.Adapter class Kotlin

I'm new to Kotlin and trying to create an alarm clock app.我是 Kotlin 的新手,正在尝试创建一个闹钟应用程序。 In this app I'm using LiveData and RecycleView.在这个应用程序中,我使用了 LiveData 和 RecycleView。 Right now I need to change the alarm status:现在我需要更改警报状态:

切换台

Here is my AlarmsRecyclerAdapter where i tried to create .onClickListener{}这是我的AlarmsRecyclerAdapter哪里我试图创建.onClickListener{}

override fun onBindViewHolder(holder: AlarmsRecyclerAdapter.AlarmItemHolder, position: Int) {
        //mAlarmViewModel = ViewModelProviders.of( context as Fragment)[AlarmViewModel::class.java]
        if (mAlarms != null) {
            val current = mAlarms!!.get(position)
            holder.view.edit_time_button.text = current.printTime()
            holder.view.switch_alarm_enabled.isEnabled = current.enabled

            holder.view.switch_alarm_enabled.setOnClickListener {
                current.enabled = !current.enabled
               // mAlarmViewModel.insert(current)
            }
        } else {
            // Covers the case of data not being ready yet.
            holder.view.edit_time_button.text = "no timer"
        }
    }

I also tried to get instance of ViewModel in the comment line, but it just throws errors like我还尝试在注释行中获取ViewModel实例,但它只会抛出类似的错误

java.lang.ClassCastException: android.app.Application cannot be cast to androidx.fragment.app.FragmentActivity at com.xxx.alarm.AlarmsRecyclerAdapter.onBindViewHolder(AlarmsRecyclerAdapter.kt:58) at com.xxx.alarm.AlarmsRecyclerAdapter.onBindViewHolder(AlarmsRecyclerAdapter.kt:33) java.lang.ClassCastException: android.app.Application 无法转换为 com.xxx.alarm.AlarmsRecyclerAdapter.onBindViewHolder(AlarmsRecyclerAdapter.kt:58) 处的 androidx.fragment.app.FragmentActivity com.xxx.alarm.AlarmsRecyclerAdapter.onBindViewHolder( AlarmsRecyclerAdapter.kt:33)

I need to change the alarms in the database, so how can I get an instance of ViewModel in the adapter class?我需要更改数据库中的警报,那么如何在适配器类中获取ViewModel的实例? Or is there better way to manage the data changing?或者有没有更好的方法来管理数据变化?

Not really sure about getting your ViewModel inside your RecyclerView, and not really sure if this would be considered best practice.不太确定将 ViewModel 放入 RecyclerView 中,也不确定这是否被视为最佳实践。 But here is the way I am doing this, and have others seen doing it.但这是我这样做的方式,其他人也看到这样做了。 First you create your ViewModel in you Fragment.首先,您在 Fragment 中创建您的 ViewModel。 Then you observe your AlarmData and when it changes you update the data in your RecyclerAdapter.然后您观察您的 AlarmData,当它发生变化时,您会更新 RecyclerAdapter 中的数据。

So in your Fragment you do something like this():所以在你的 Fragment 你做这样的事情():

mAlarmViewModel = ViewModelProviders.of( context as Fragment)[AlarmViewModel::class.java]
mAlarmViewMode.getAlarms().observe(...
    mAdapter.setData(newData)

and inside you Adapter you add the following:并在您的 Adapter 中添加以下内容:

setData(data:List) {
    mAlarms= data;
    notifyDataSetChanged();
}    

this should keep your data updated.这应该使您的数据保持更新。

Now for the changing of your data.现在更改您的数据。 Try Setting the OnclickListener inside your ViewHolder, as this is going to increase the speed of your app.尝试在您的 ViewHolder 中设置 OnclickListener,因为这将提高您的应用程序的速度。 to get your current value you could do this:要获得您的当前价值,您可以这样做:

val current = mAlarms!!.get(getAdapterPosition())

Finally you shold add a Interface to your Adapter, something like this:最后,您应该向您的适配器添加一个接口,如下所示:

interface ItemSelectedListener {
  fun onItemSelected(item:Any, v:View)
}

Set this interface from your Fragment and call it from the onClickListener.从您的 Fragment 设置此接口并从 onClickListener 调用它。 Then you have all the data you need inside your Fragment and can modify it from there然后你在你的 Fragment 中拥有你需要的所有数据,并且可以从那里修改它

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM