Before I explain my problem, I want to say that I have already seen all the related questions but none of them worked for me.
I am a beginner in Android. I am using a custom view class, let's say CustomView which looks like:
class CustomView(context: Context?,attributeSet: AttributeSet) : View(context) {
class CustomView constructor(context: Context?, attributeSet: AttributeSet){
}
var number = 1
}
I am inflating this view inside a fragment resource, like:
<com.example.myapp.CustomView
android:id="@+id/custom_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
But now whenever I am trying to get the custom view, it is null. All the sibling views work fine.
val root = inflater.inflate(R.layout.fragment_main, container,false)
val customView: CustomView = root.findViewById(R.id.custom_view)
It is throwing an error
java.lang.IllegalStateException: findViewById(R.id.custom_view) must not be null
You need to pass that AttributeSet
parameter into the View
superclass constructor:
To allow Android Studio to interact with your view, at a minimum you must provide a constructor that takes a
Context
and anAttributeSet
object as parameters. This constructor allows the layout editor to create and edit an instance of your view.
(https://developer.android.com/training/custom-views/create-view#subclassview)
So:
class CustomView(context: Context?,attributeSet: AttributeSet) : View(context, attributeSet) {
If you like, this is the standard boilerplate, overloaded custom view constructor (that the IDE will generate for you):
class CustomView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr)
That has some edge case theming compromises but it's usually fine, and handles whichever constructor the system wants to use.
(Also you don't need that nested CustomView
class in your code)