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)
this worked for me. But one more thing how do I get and update the number property and display the updated value in the fragment?
Are you sure you want to create a custom view? If so you should read some tutorials on it, it's a little advanced. If not my advice is don't bother, stick a
TextView
in your fragment's layout and update it in your fragment code. If you're a beginner, you really don't want to do this unless you have to!Basically I wanted to implement it on a paint app where a CustomView serves as a canvas to draw and it will be inflated inside the fragment. So, I wanted to modify the pen size and color from the fragment. Before, I could do that I thought it would be better to understand how things work with a basic example, so I chose this. I am planning to have a public pen size property inside the custom view which I can update from the fragment and start to draw with new pen size.
Ok, you really need to read up on this, but you can either inflate a layout inside your custom view (like with a Fragment), or you can draw to a
Canvas
, which is what you want to do. You basically implementonDraw
and use the drawing commands (likedrawText
ordrawLine
) using aPaint
. So if you want to write a number, you can usedrawText
. But honestly, I feel like what you're doing is one of the more advanced uses of custom views (touch and everything) so finding a paint app tutorial might be your best bet, something that shows you how it all basically works