Custom Views - II08 Mar 2017 Android #android #views
This is part 2 of two part series
In part 1, I have discussed core view classes and view types of view constructor. This article focuses on view drawing in its layout in parent view.
At high level, a view is created in two phases.
- Layout Phase
- Drawing Phase
In layout phase, view parent determines the size and layout of a view, it calculates the size of view and place for laying out view. Layout phase is completed in 2 passes.
- Measure Pass
- Layout Pass
In measure pass, size of a view is calculated (when it wants to know how big a view can be). It starts when a view parent calls
method of view with appropriate
MeasureSpecs. This method does some work and calls
in custom view.
Parameters passed to
onMeasure(...) are special parameters. They have
integer type but they are actually two parameters encoded
in a single integer. Each parameter has a mode and size value and these values can be retrieved by passing it
Mode gives you a clue about how big a view should be. Mode can be one of the following
This mode tells that parent has measure the size of child view and view should have this size.
onMeasure is called with this mode
when view is specified in
xml with size equals to
match_parent or exact size in dps e.g. 40dp.
onMeasure is called with his mode bit if view is specified in
xml with size equals to
wrap_content. With this mode bit, android tells that
I have this size and you can draw your view with in this size.
This mode is used when android system wants to query how big this view can be. It’s our responsibliy to provide the system with appropriate size.
Setting size in
In measure pass, after calling
onMeasure, parent views expects us to set the size of view using
After calculating size (based on mode bit or any other logic) you must pass this size to parent using above method, failing to call
this method will trigger
IllegalStateException at runtime.
Default implementation of
The default implementation of
setMeasuredDimension by getting width and height from
getDefaultSize returns the same size for both
Layout pass sets the size of view by using dimensions set in
onMeasure. This pass is started when parent view calls
of view followed by calling
onLayout(...) in derived view.
After setting the size on view, it calls
onSizeChanged(..) if the size of view is changed.
Default implementation of both
onLayout is no-op.