问题描述
我在 viewmodel 中实例化了一个 Graph 对象,我试图将它传递给我创建的自定义画布视图,但我不断收到“尝试调用虚拟方法......在空对象引用上”的消息
自定义画布视图
Class DesignCanvasView @JvmOverloads constructor(
context: Context,attrs: AttributeSet? = null,defStyleAttr: Int = 0
) : View(context) {
private lateinit var extraCanvas: Canvas
private lateinit var extraBitmap: Bitmap
lateinit var graph : Graph
片段 class DesignFragment : Fragment() {
private lateinit var binding : DesignFragmentBinding
private lateinit var viewmodel: designviewModel
companion object {
fun newInstance() = DesignFragment()
}
override fun onCreateView(inflater: LayoutInflater,container: ViewGroup?,savedInstanceState: Bundle?): View? {
binding = DataBindingUtil.inflate(inflater,R.layout.design_fragment,container,false)
viewmodel = viewmodelProvider(this).get(designviewModel::class.java)
viewmodel.graph.observe(viewLifecycleOwner,Observer {
binding.designCanvasView.graph = it
})
return binding.root
}
}
视图模型
class designviewModel : viewmodel() {
val graph = mutablelivedata<Graph>(Graph())
}
错误味精
编辑 布局代码
<?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"
xmlns:tools="http://schemas.android.com/tools">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".screens.design.DesignFragment">
<com.example.druggame.screens.design.DesignCanvasView
android:id="@+id/designCanvasView"
android:layout_width="match_parent"
android:layout_height="450sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.4"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.5">
</com.example.druggame.screens.design.DesignCanvasView>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
提前感谢您的帮助。
解决方法
问题实际上与数据绑定无关,而是因为您的自定义视图。您的构造函数接受数据绑定所需的 AttributeSet
,但您从未将其传递给超类 (View
)。所以它应该看起来像这样:
class DesignCanvasView @JvmOverloads constructor(
context: Context,attrs: AttributeSet? = null,defStyleAttr: Int = 0
) : View(context,attrs,defStyleAttr)
还有一些其他注意事项。建议您使用单独的绑定类来扩展您的绑定,而不是通用 DataBindingUtil
,除非您有特定的理由这样做。
其次,将所有与视图相关的逻辑(不是)作为 onViewCreated
而不是 onCreateView
中的初始绑定通常是一种很好的做法。
最后,虽然在您的情况下绑定不需要生命周期所有者,但您应该始终坚持使用通过 viewLifecycleOwner
检索的视图所有者作为您的绑定(但是,同样,只有当您不有一个具体的不)。