Draw Line Using Ondraw Android Dev
Example
In one of my projects, I had the requirement of creating a circular TextView to display the count of notifications. Here we need to create a subclass of TextView.
Step 1: Create a class with the name CircularTextView.
Step 2: Extend the TextView widget class. Now, the IDE pops an error on TextView saying this type has a constructor and must be initialized here.
Step 3: Add constructors to the class.
This can be done in two ways
One way is by adding constructors to the class as below.
The other way is by adding @JvmOverloads to the constructor invocation as shown below.
Usually, we get confused about why there are different types of constructors for a View.
View(Context context)
Simple constructor to use when creating a view from code dynamically. Here the parameter context is the context in which the view is running in through which it can access the current theme, resources, etc.
View(Context context, @Nullable AttributeSet attrs)
Constructor that is called when inflating a view from XML. This is called when a view is being constructed from an XML file, supplying attributes that were specified in the XML file. This version uses a default style of 0, so the only attribute values applied are those in the Context's Theme and the given AttributeSet.
Step 4: The most important step in drawing a custom view is to override the onDraw() and implementation of your logic inside it.
OnDraw(canvas: Canvas?) has a parameter Canvas by which the view component can draw itself. To draw on canvas it's necessary to create a Paint object.
Mainly drawing is divided into two areas
- What to draw, handled by Canvas
- How to draw, handled by Paint.
Canvas provides a method to draw a line while Paint provides methods to define that line's color. In our example of CircularTextView Canvas provides a method to draw a circle while Paint object fills the color. Simply we can say that Canvas defines shapes that you can draw on the screen while Paint defines the properties like color, style, font, etc., of each shape you draw.
Let's get into coding. We create a Paint object and assign some properties to it and then draw the shape on Canvas using that Paint object. onDraw() will simply look as following
IDE shows a warning to avoid object allocations during draw/layout operations. Because the onDraw() method gets called many times while rendering a view that creates unnecessary objects every time. So to avoid this unnecessary object creation we need to move this part out of onDraw() as shown below.
While performing drawing, always keep in mind to reuse objects instead of creating new ones. Don't rely on your IDE that will highlight a potential issue but do it yourself because IDE could not see it if you create objects inside methods called from onDraw().
Step 5: Now we are done with drawing let us inflate this view class in XML.
Add this XML layout to your Activity and run the application. The following will be the output.
That's awesome, right? Now let's make this circlePaint color dynamic property assigned from activity along with some stroke. For this, we need to create some setter methods in our CircularTextView class so that we can call these methods and set the properties dynamically.
Initially, let's configure a paint color. For this, we create a setter method as below.
fun setSolidColor(color: String) {
solidColor = Color.parseColor(color)
circlePaint?.color = solidColor
}
Now, from Activity, we can set color dynamically by calling this method.
circularTextView.setSolidColor("#FF0000")
That's cool, right? Now let's add some stroke to the circle. For stroke, there are two inputs required: stroke width and stroke color. For stroke color, we need to create a Paint object the same as we did for Circle above. For stroke width, we create a variable and set that value to it and use that value in onDraw(). The complete code will be simply as following.
And from activity dynamically set the attributes to customize it.
Now let us run the application setting different colors.
Now we have got an idea of how to set properties dynamically from Activity, but there would be a question of how to set attributes from XML. Let's continue further to explore.
For this, we firstly create a new file in your values folder with name attrs.xml. This file contains all the attributes for different custom views. In the below example we have a view called CircularTextView with an attribute named ct_circle_fill_color which takes color input. Similarly, we can add other attributes too.
Then secondly, we need to read these properties in our Custom View class. From init block, we read the attributes set as shown below
val typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.CircularTextView)
circlePaint?.color = typedArray.getColor(R.styleable.CircularTextView_ct_circle_fill_color,Color.BLUE)
typedArray.recycle()
Now, simply go to XML and set the property value to whichever color you want and run the application. You will see the required output.
app:ct_circle_fill_color="@color/green"
In my case the output was.
Note: Don't hard code your view size while drawing, because other developers could have the same view but in different sizes. So draw your view depending on what size it has.
Draw Line Using Ondraw Android Dev
Source: https://betterprogramming.pub/draw-custom-views-in-android-a321fa157d60