Slide 1

Slide 1 text

A C A C C C C C Xavier Rubio Jansana  @teknik_tdr  https://xrubio.com  https://github.com/xrubioj/

Slide 2

Slide 2 text

W ? W ? Controls that don't exist in Android Compound Controls ("Group of Views") Customization of controls

Slide 3

Slide 3 text

W ? W ? No similar control exists Same groups of controls repeats Theming is not enough

Slide 4

Slide 4 text

B B Encapsulate and simplify common controls Create a design language Simplify maintenance

Slide 5

Slide 5 text

C C C C 1. Extend a ViewGroup (e.g. LinearLayout, ConstraintLayout...) 2. Inflate the layout and attach it 3. ... 4. Profit!

Slide 6

Slide 6 text

C C C C C C class MyCompoundControlView @JvmOverloads constructor( context: Context?, attrs: AttributeSet? = null, defStyleAttr: Int = 0, defStyleRes: Int = 0 ) : LinearLayout(context, attrs, defStyleAttr, defStyleRes) { init { View.inflate(context, R.layout.my_compount_control_layout, this) } }

Slide 7

Slide 7 text

C C L C C L

Slide 8

Slide 8 text

C C R C C R

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

C C L C C L ( ) ( ) Notice and tool

Slide 11

Slide 11 text

C C U C C U Initialization of root tag moved here class MyCompoundControlView @JvmOverloads constructor( context: Context?, attrs: AttributeSet? = null, defStyleAttr: Int = 0, defStyleRes: Int = 0 ) : LinearLayout(context, attrs, defStyleAttr, defStyleRes) { init { View.inflate(context, R.layout.my_compount_control_layout, this) this.orientation = VERTICAL } }

Slide 12

Slide 12 text

C C R C C R

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

C C U C C U Notice we're using the fully qualified class name

Slide 15

Slide 15 text

UI D S UI D S 1. Measure: calculate dimensions based in constraints  2. Layout: layout children → we don't need it 3. Draw: use Canvas to draw 

Slide 16

Slide 16 text

M M We have a measureSpec per axis (X & Y) UNSPECIFIED EXACTLY AT_MOST val specMode: Int = MeasureSpec.getMode(measureSpec) val specSize: Int = MeasureSpec.getSize(measureSpec)

Slide 17

Slide 17 text

M M override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpe val minW: Int = (paddingStart + paddingEnd + _radius * 2.0 val w: Int = resolveSizeAndState(minW, widthMeasureSpec, 0 val minH: Int = (paddingTop + paddingBottom + _radius * 2. val h: Int = resolveSizeAndState(minH, heightMeasureSpec, setMeasuredDimension(w, h) }

Slide 18

Slide 18 text

M M Units are pixels Must call setMeasuredDimension() Use resolveSizeAndState(size, measureSpec, childMeasuredState) as helper

Slide 19

Slide 19 text

C C Units are pixels Top-le is (0, 0) Draws in order ("on top of")

Slide 20

Slide 20 text

C . P C . P Canvas is where things are drawn Paint is how things are drawn Canvas can get a backing Bitmap

Slide 21

Slide 21 text

C C drawBitmap() drawRect(), drawCircle(), etc. drawColor() drawText() clip*()

Slide 22

Slide 22 text

P P A er changind a property, we need to either invalidate or relayout: invalidate(): triggers a redraw. Use when property doesn't changes size. requestLayout(): triggers the whole cycle (measure, layout, draw). Use when property changes size.

Slide 23

Slide 23 text

C KTX C KTX Helps cleanup code (avoiding save() and restore(), for instance) withClip(), withMatrix(), withRotation, etc. See: implementation 'androidx.core:core-ktx:1.1.0' https://developer.android.com/reference/kotlin/androidx/core/graphics/package- summary

Slide 24

Slide 24 text

R R Custom View Components at developer.android.com "Tips for Building Custom Views on Android with Canvas APIs" slides, Rebecca Franks Android Canvas APIs with Kotlin and KTX https://developer.android.com/guide/topics/ui/cust components https://speakerdeck.com/riggaroo/tips-for-building custom-views-on-android-with-canvas-apis https://riggaroo.co.za/android-canvas-apis-with-ko and-ktx/

Slide 25

Slide 25 text

O R O R Source code of View#resolveSizeAndState(int, int, int) in AOSP What's the utility of the third argument of View.resolveSizeAndState()? https://android.googlesource.com/platform/frameworks/base/+/ refs/heads/master/core/java/android/view/View.java#24704 https://stackoverflow.com/questions/13650903/ whats-the-utility-of-the-third-argument-of-view- resolvesizeandstate/<13651513#13651513

Slide 26

Slide 26 text

Q ? Q ?

Slide 27

Slide 27 text

T ! T ! Xavier Rubio Jansana This talk is available at:  @teknik_tdr  https://xrubio.com  https://github.com/xrubioj/ https://xrubio.com/talks/talk-android-custom-controls-and-canvas/