Kotlin/Android:无法使用 Canvas 将 LiveData 传递给 customView
Kotlin/Android : Cannot pass LiveData to customView with Canvas
我在 ViewModel 中实例化了一个 Graph 对象,我试图将它传递给我创建的自定义 canvas 视图,但我不断收到消息“尝试调用虚拟方法...在 null 上对象引用
下面我 post 我的代码和错误日志。
自定义Canvas视图
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 设计片段:片段(){
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
检索的视图所有者作为您的绑定(但是,同样,只有当您不没有具体的不要)。
我在 ViewModel 中实例化了一个 Graph 对象,我试图将它传递给我创建的自定义 canvas 视图,但我不断收到消息“尝试调用虚拟方法...在 null 上对象引用
下面我 post 我的代码和错误日志。
自定义Canvas视图
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 设计片段:片段(){
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
检索的视图所有者作为您的绑定(但是,同样,只有当您不没有具体的不要)。