【问题标题】:What do I get the error Smart cast to 'HomeViewModel' is impossible when I use data binding in Android Studio?当我在 Android Studio 中使用数据绑定时,我会得到什么错误 Smart cast to 'HomeViewModel' is possible?
【发布时间】:2020-08-27 06:43:17
【问题描述】:

我使用<variable name="aHomeViewModel"type="info.dodata.voicerecorder.viewcontrol.HomeViewModel" />HomeViewModel绑定到layout.xml

运行代码时出现以下错误。

智能转换为“HomeViewModel”是不可能的,因为“binding.aHomeViewModel”是一个可变属性,此时本可以更改

我认为是binding.aHomeViewModel.delete(binding.amVoice) 导致了错误,我该如何解决?

VoiceAdapters.kt

class VoiceAdapters (private val aHomeViewModel: HomeViewModel):
        ListAdapter<MVoice, VoiceAdapters.VoiceViewHolder>(MVoiceDiffCallback()) {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VoiceViewHolder {
        return VoiceViewHolder(
            LayoutVoiceItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        )
    }

    override fun onBindViewHolder(holder: VoiceViewHolder, position: Int) {
        val aMVoice = getItem(position)
        holder.bind(aHomeViewModel, aMVoice)
    }

    class VoiceViewHolder (private val binding: LayoutVoiceItemBinding):
          RecyclerView.ViewHolder(binding.root) {

        init {
            setControl()
        }

        private fun navigateToDetail( view: View,  aMVoice: MVoice )
        {
            val direction = FragmentHomeDirections.actionHome2Detail(aMVoice)
            view.findNavController().navigate(direction)
        }

        fun bind(aHomeViewModel: HomeViewModel, aMVoice: MVoice){
            binding.amVoice=aMVoice
            binding.aHomeViewModel=aHomeViewModel
            binding.executePendingBindings()
        }

        fun setControl(){              
            binding.btnDelete.setOnClickListener {
                binding.amVoice?.let {
                  binding.aHomeViewModel?.let {
                     binding.aHomeViewModel.delete(binding.amVoice)  //I think it cause error.
                  }
              }
            }
        }
    }

}


class MVoiceDiffCallback : DiffUtil.ItemCallback<MVoice>() {
   ...
}

HomeViewModel.kt

class HomeViewModel(private val mDBVoiceRepository: DBVoiceRepository) : ViewModel() {
    ...
    
    fun delete(aMVoice: MVoice){
        viewModelScope.launch {
            mDBVoiceRepository.deleteVoice(aMVoice)
        }
    }

}

layout.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">

<data>
    <variable name="aMVoice"
        type="info.dodata.voicerecorder.model.MVoice"  />

    <variable name="aHomeViewModel"
        type="info.dodata.voicerecorder.viewcontrol.HomeViewModel" />
</data>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="?android:attr/listPreferredItemHeight"
    android:orientation="horizontal">

    <TextView
       android:id="@+id/voiceID"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="@{Integer.toString(aMVoice.id)}" />

    <TextView
        android:id="@+id/title_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="50dp"
        android:text="@{aMVoice.name}" />
    ...
</LinearLayout>

</layout>

添加内容

如果我使用Code A,我会得到新的编译警告信息Warning A。

代码 A

binding.btnDelete.setOnClickListener {
    binding.aHomeViewModel!!.delete(binding.amVoice!!)
}

警告 A

此版本中使用了已弃用的 Gradle 功能,使其与 Gradle 7.0 不兼容。 使用“--warning-mode all”显示个别弃用警告。

【问题讨论】:

    标签: android android-databinding


    【解决方案1】:

    HomeViewModel 是一个可变属性,此时可能已更改。需要使用 !!? 运算符的安全调用

    【讨论】:

    • 谢谢!请您看看我在问题中添加的内容吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-09
    相关资源
    最近更新 更多