Custom View Lifecycle and Some Tips

By Farzad Nazifi on Unsplash

For an Android developer, you might be familiar with the lifecycle for Activities and Fragments, but you might not be aware of the custom view lifecycle. If you are confused about it, the goal of this article is to answer most of your questions.

When a view is created, this is the order in which the following methods are called:

1. Constructor

  • CustomView(Context context) (if created programmatically)
  • CustomView(Context context, AttributeSet attrs) (if created from xml)

2. onFinishInflate (assuming you used the xml constructor)

3. onAttachedToWindow

4. onMeasure

5. onSizeChanged

6. onLayout

7. onDraw

The earliest you can get the view’s measurements is in onMeasure. Before that the width and height are 0. However, the only thing you should be doing in onMeasure is determining the size of the view. This method gets called several times while the view is telling the parent how big it wants to be, but the parent is determining the actual final size.

If you want to actually use the measured size for anything, the earliest place to do that is in onSizeChanged. It gets called whenever the view is created because the size is changing from 0 to whatever the size will be.

Unlike onMeasure, onLayout is called only once during the traversal. So it is recommended to perform any complex calculations in this method.

You can also access the size in onDraw with getMeasuredWidth() and getMeasuredHeight(). However, if you are using them to do any heavy calculations, it is better to do that beforehand. Generally speaking, try to keep as much out of onDraw as possible since it may be called multiple times. (It gets called whenever invalidate() gets called.)

The difference between invalidate() and requestLayout():

  • invalidate() method used to simple redrawing view. While our view, for example, updates its text, color or touch interactivity. It means that view will only call onDraw() method once more to update its state.

Tips: when dealing with animation, we need to call invalidate() to draw it. We need to call invalidate() every time new animated values comes out.

  • requestLayout() method, as you can see it will produce view update through its lifecycle just from onMeasure() method. This means that you will need it after your view updates. Since it changed its size, you need to measure it once again to draw it depending on the new size.

Difference between getHeight() and getMeasuredHeight:

The size of a view is expressed with a width and a height. A view actually possess two pairs of width and height values.

The first pair is known as measured width and measured height. These dimensions define how big a view wants to be within its parent (see Layout for more details.) The measured dimensions can be obtained by calling getMeasuredWidth() and getMeasuredHeight().

The second pair is simply known as width and height, or sometimes drawing width and drawing height. These dimensions define the actual size of the view on screen, at drawing time and after layout. These values may, but do not have to, be different from the measured width and height. The width and height can be obtained by calling getWidth() and getHeight().

As ever, QuarkWorks is available to help with any software application project — web, mobile, and more! If you are interested in our services you can check out our website. We would love to answer any questions you have! Just reach out to us on our Twitter, Facebook, or LinkedIn.