I've instanciated a Graph object in ViewModel and Im trying to pass it to the custom canvas view I made but I keep getting the messages that "Attempt to invoke virtual method ... on a null object reference"
Bellow I post my code and error log.
Custom Canvas View
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
Fragment 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
}
}
ViewModel
class DesignViewModel : ViewModel() {
val graph = MutableLiveData<Graph>(Graph())
}
EDIT Layout code
<?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>
Thanks for any help in advance.
The issue isn't actually really data binding related but is because of your custom view. Your constructor takes in an AttributeSet
as required for data binding, but you never pass it to the superclass (View
). So instead it should look like this:
class DesignCanvasView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr)
Just a couple of other notes. You are recommended to use the individual binding classes to inflate your bindings, not the generic DataBindingUtil
unless you have a specific reason to do so.
Secondly it is generally good practice to have all your view-related logic that isn't the initial binding in onViewCreated
instead of onCreateView
.
Then finally, although in your case the binding doesn't need a lifecycle owner, you should always stick to using the view's owner retreived with viewLifecycleOwner
for your bindings (however, again, only if you don't have a specific not to).