Kotlin/Android:无法使用 Canvas

问题描述

我在 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())
}

错误味精

Error

编辑 布局代码

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