Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Don’t Fear the Canvas (Android KW June 2016)

Don’t Fear the Canvas (Android KW June 2016)

Android provides a wide variety of built-in views and layouts. Sometimes designs can’t be created with these views. Other times implementing a design with these views requires a complex view hierarchy. This talk will cover how to create custom views targeted to your needs. I’ll explain when and when not to go custom, and provide tips and tricks for getting the most out of your views.

https://www.youtube.com/watch?v=KH8Ldp39TUk

Matthew Precious

June 28, 2016
Tweet

More Decks by Matthew Precious

Other Decks in Programming

Transcript

  1. public class CustomView extends LinearLayout { public void show() {

    //  } }x b i n d ( D a t a d a t a ) }x
  2. M

  3. A

  4. J

  5. S

  6. S

  7. S

  8. S

  9. S

  10. S

  11. M

  12. M

  13. M

  14. Canvas • drawLine() • drawRect() • drawOval() • drawText() •

    drawColor() • drawPath() • drawBitmap() • …
  15. Canvas • drawLine() • drawRect() • drawOval() • drawText() •

    drawColor() • drawPath() • drawBitmap() • … • translate()
  16. Canvas • drawLine() • drawRect() • drawOval() • drawText() •

    drawColor() • drawPath() • drawBitmap() • … • translate() • scale()
  17. Canvas • drawLine() • drawRect() • drawOval() • drawText() •

    drawColor() • drawPath() • drawBitmap() • … • translate() • scale() • rotate()
  18. Canvas • drawLine() • drawRect() • drawOval() • drawText() •

    drawColor() • drawPath() • drawBitmap() • … • translate() • scale() • rotate() • skew()
  19. Canvas • drawLine() • drawRect() • drawOval() • drawText() •

    drawColor() • drawPath() • drawBitmap() • … • translate() • scale() • rotate() • skew() • clipRect()
  20. Canvas • drawLine() • drawRect() • drawOval() • drawText() •

    drawColor() • drawPath() • drawBitmap() • … • translate() • scale() • rotate() • skew() • clipRect() • …
  21. @Override protected void onDraw(Canvas canvas) { canvas.drawRect(5, 5, 10, 10,

    paint); canvas.translate(5, 15); canvas.drawOval(0, 0, 5, 5, paint); }x
  22. @Override protected void onDraw(Canvas canvas) { canvas.drawRect(5, 5, 10, 10,

    paint); canvas.translate(5, 15); canvas.drawOval(0, 0, 5, 5, paint); }x
  23. @Overrideyprotected void onMeasure(…) {
 super.onMeasure(…);
 bounds.set(0, 0, getMeasuredWidth(), getMeasuredHeight());
 }

    @Override protected void onDraw(Canvas canvas) { canvas.drawOval(bounds, backgroundPaint); super.onDraw(canvas); }x
  24. M

  25. @Override protected void onDraw(Canvas canvas) { canvas.drawOval(bounds, backgroundPaint); int textBottom

    = round((bounds.height() / 2f) + (textBounds.height() / 2f)); super.onDraw(canvas); canvas.drawOval(bounds, borderPaint); if (isPressed()) {
 canvas.drawOval(bounds, pressPaint);
 }y }x
  26. @Override protected void onDraw(Canvas canvas) { canvas.drawOval(bounds, backgroundPaint); int textBottom

    = round((bounds.height() / 2f) + (textBounds.height() / 2f)); canvas.drawText(initial, width / 2f, textBottom, textPaint); super.onDraw(canvas); canvas.drawOval(bounds, borderPaint); if (isPressed()) {
 canvas.drawOval(bounds, pressPaint);
 }y }x
  27. M

  28. M

  29. S

  30. S M

  31. attrs.xml <declare-styleable name="AvatarView">
 <attr name="textColor" format="color"/>
 <attr name="textSize" format="dimension"/>
 <attr

    name="borderColor" format="color"/>
 <attr name="borderWidth" format="dimension"/>
 <attr name="pressColor" format="color"/>
 </declare-styleable>
  32. attrs.xml <declare-styleable name="AvatarView">
 <attr name="android:textColor"/>
 <attr name="android:textSize"/>
 <attr name="borderColor" format="color"/>


    <attr name="borderWidth" format="dimension"/>
 <attr name="pressColor" format="color"/>
 </declare-styleable> 
 format="color"
 format="dimension"

  33. TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AvatarView, 0, 0); int borderColor =

    a.getColor( R.styleable.AvatarView_borderColor, defaultBorderColor);
 int borderWidth = a.getDimensionPixelSize( R.styleable.AvatarView_borderWidth, defaultBorderWidth);
 // 
 a.recycle();
  34. PathEffect pathEffect = new DashPathEffect( new float[] { dashLength, dashGap

    }, phase);
 strokePaint.setPathEffect(pathEffect);
  35. PathEffect pathEffect = new DashPathEffect( new float[] { dashLength, dashGap

    }, phase);
 strokePaint.setPathEffect(pathEffect); Romain Guy PathEffect
  36. No.

  37. Tips • Don’t break Preview • isInEditMode() • Embrace Preview

    • isInEditMode() • tools: • Translate/scale/rotate
  38. Tips • Don’t break Preview • isInEditMode() • Embrace Preview

    • isInEditMode() • tools: • Translate/scale/rotate • Save/restore
  39. Tips • Don’t break Preview • isInEditMode() • Embrace Preview

    • isInEditMode() • tools: • Translate/scale/rotate • Save/restore • Be aware of pixel boundaries
  40. Tips • Don’t break Preview • isInEditMode() • Embrace Preview

    • isInEditMode() • tools: • Translate/scale/rotate • Save/restore • Be aware of pixel boundaries • Cast/round to int
  41. Tips • Don’t break Preview • isInEditMode() • Embrace Preview

    • isInEditMode() • tools: • Translate/scale/rotate • Save/restore • Be aware of pixel boundaries • Cast/round to int • Inset/translate strokes