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

时间:2019-03-28 19:03:58

标签: android mvvm kotlin android-recyclerview

我是Kotlin的新手,正在尝试创建闹钟应用。在这个应用程序中,我使用LiveData和RecycleView。现在我需要更改警报状态:

switcher

这是我的 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"
        }
    }

我也尝试在注释行中获取ViewModel的实例,但它只会引发

之类的错误。
  

java.lang.ClassCastException:android.app.Application无法转换为androidx.fragment.app.FragmentActivity           在com.xxx.alarm.AlarmsRecyclerAdapter.onBindViewHolder(AlarmsRecyclerAdapter.kt:58)           在com.xxx.alarm.AlarmsRecyclerAdapter.onBindViewHolder(AlarmsRecyclerAdapter.kt:33)

我需要数据库中的更改警报。那么如何在适配器类中获取ViewMoedel的实例?还是有更好的方法来管理数据更改?

1 个答案:

答案 0 :(得分:1)

不太确定是否将ViewModel放入RecyclerView中,也不确定是否将其视为最佳做法。但是,这是我执行此操作的方式,并且看到其他人正在执行此操作。 首先,您在Fragment中创建ViewModel。 然后观察您的AlarmData,并在其更改时更新RecyclerAdapter中的数据。

因此,在您的Fragment中,您将执行以下操作:

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

在适配器内部添加以下内容:

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

这应该使您的数据保持更新。

现在用于更改数据。 尝试在ViewHolder中设置OnclickListener,因为这将提高应用程序的速度。 要获取当前值,您可以执行以下操作:

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

最后,您要向适配器添加接口,如下所示:

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

从您的Fragment设置此接口,然后从onClickListener调用它。 然后,您可以在Fragment中拥有所需的所有数据,并可以在其中进行修改