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 检索的视图所有者作为您的绑定(但是,同样,只有当您不没有具体的不要)。