How to build a custom drawing with canvas?
Various applications are used daily, almost a ton but they are almost similar in so many ways and indistinguishable. That’s why it is critical to modify layouts and appearances that no other application had made yet to stand out and be remarkable from others.
Implementing a custom view takes a decent amount of time. So to save your time, this article is made based on these views to simplify the process.
When to draw?
Well, since the majority of custom perspectives are additional tedious than the normal ones, you should just make it, if there is no less demanding approach to execute a particular feature or you have the accompanying issues that custom view could have settled
Well, since most of custom views are more time consuming than the regular ones, you should only make it, if there is no easier way to implement a specific feature or you have the following issues that custom view could have resolved:
- Performance. when you have a lots of views in your layout and you want to optimize it by way of drawing a single custom view to make it lighter.
- A huge view hierarchy that is complicated to function and support.
- An entire custom view that requires manually drawing.
if you have not tried working out a custom view, then this article is a brilliant opportunity to stay in the direction of drawing your very own flat custom view. it’s going to show you the overall view structure, the way to enforce specific things, how to avoid common mistakes and even a way to animate your view!
First lets dive into view lifecycle. for some reason Google does not provide an official diagram of view lifecycle, it’s far quite a significant false impression among developers that leads to surprising bugs and problems, so lets keep our eye on it!
Which the view starts its lifecycle from. it allow us to initial the drawings, set the default values, make calculations and whatever we need as the view is initializing.
” The view is attached to a window. At this point it has a Surface and will start drawing. Note that this function is guaranteed to be called before onDraw(android.graphics.Canvas), however it may be called any time before the first onDraw — including before or after onMeasure(int, int).”
– developer.android.com –
At this stage – if you needed you – can find the surrounding views by id and save a global reference for them to use these views must be on the same ‘layout.xml’.
This stage for the view to find its size.
while overriding, what you need to do is to set setMeasuredDimension(int width, int height)
What happens with measure is that starting at the root, and again, going down from parents to children, the parent will figure out some constraints for each of its children on how big they can be. that child will take those constraints and determine out, “given what the parent advised me about how big i can be, here is how big i can be.” then it keeps that to itself until the parent is ready afterward to read that data. in the process of calculating it’s width and height, that child may certainly measure any children that it has a well. once more, it’s far a recursive process.
to calculate the size right , some steps need to be achieved:
- Calculate your view content desired size (width and height).
- Get your view MeasureSpec (width and height) for size and mode.
- Check MeasureSpec mode that user sets and adjusts the size of his/her view (for width and height).
- MeasureSpec.EXACTLY The parent has determined an exact size for the child. The child is going to be given those bounds regardless of how big it wants to be (user hardcoded the size value).
- MeasureSpec.AT_MOST The child can be as large as it wants up to the specified size.
- MeasureSpec.UNSPECIFIED The parent has not imposed any constraint on the child. It can be whatever size it wants.
“Called from layout when this view should assign a size and position to each of its children”
– developer.android.com –
This method, consists of assigning a size and position to every of its children. because of that, we are searching into a flat custom view (that extends a easy view) that doesn’t have any children so there’s no cause to override this technique.
(The magic Factory) onDraw
Having both Canvas and Paint objects will allow you to draw anything that you need and that’s where the magic happens!
A Canvas instance comes as onDraw parameter, is basically a response to drawing different shapes that the view can use to draw itself, while Paint object holds the style and color that the shape will get. Simply,canvas respond for drawing an object, while Paint is for styling it. And it’s used mostly everywhere whether it is going to be a line, circle or rectangle.
while making a custom view, always take in mind that onDraw calls plenty of time, like actually lots. While having a few changes, scrolling, swiping your view can be redrawn. so that’s why even android studio recommend to avoid object allocation at some point of onDraw operation, as a substitute create it once and reuse it later on.
- While performing drawing, always keep in mind to reuse objects instead of creating new ones..
- Don’t hard code your view size while drawing. Handle case that other developers could have the same view but in different size, so draw your view depending on what size it has.
invalidate() and requestLayout() those methods force the view to redraw itself helping you to make an interactive custom view. but what the difference between those two methods?.
invalidate() method is used to simply redraw view. For example, while your view updates its animation values, color or touch interactivity. It means that the view will only call onDraw() method once more to update its state.
requestLayout() method, as you can see will produce view update through its lifecycle just from onMeasure() method. And what it means is that you’ll need it right after your view updates, changed size and you want to measure it over again to draw it relying on the brand new size.
Animations in custom view is a frame by frame process. it means that in case you need to make a circle radius animated from smaller to larger, you will need to increase it sequentially and after each step call invalidate to draw it.
Your best friends in custom view animations are ValueAnimator and ObjectAnimator.
Don’t forget to call invalidate every time a new animated value comes out.
Hopefully this article will help you to draw your first custom view and if you want to learn more about it, watch this presentation video.