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

Inside Android KTX

Inside Android KTX

Talk given at Kotlin Night 2018 Milan, A Kotlin Perspective and Droidcon Turin 2018

6923bdeb363961b064d2cdb6329982d6?s=128

Roberto Orgiu

March 12, 2018
Tweet

More Decks by Roberto Orgiu

Other Decks in Programming

Transcript

  1. Inside Android KTX

  2. Rob

  3. Such magic Much tech NOPE

  4. animator = ObjectAnimator.ofFloat(view, View.ALPHA, 0f, 1f)

  5. animator = ObjectAnimator.ofFloat(view, View.ALPHA, 0f, 1f) animator.doOnStartT{ ... }T animator.doOnEndT{

    ... }T animator.doOnCancelT{ ... }T animator.doOnRepeatT{ ... }T animator.doOnPauseT{ ... }T animator.doOnResumeT{ ... }T
  6. animatorT= ObjectAnimator.ofFloat(view, View.ALPHA, 0f, 1f) animator.doOnStartT{ ... }T animator.doOnEndT{ ...

    }T animator.doOnCancelT{ ... }T animator.doOnRepeatT{ ... }T animator.doOnPauseT{ ... }T animator.doOnResumeT{ ... }T Animator.doOnStart
  7. funTAnimator.doOnStart(action:T(anim:JAnimator)T->KUnit) T= addListener(onStartT=Taction) animator.doOnStartT{ ... }

  8. fun Animator.addListener(T onEnd:T((animator:TAnimator)T->TUnit)?T=Tnull,T onStart:T((animator:TAnimator)T-> Unit)?T=Tnull,T onCancel:T((animator:TAnimator)T-> Unit)?T=Tnull,T onRepeat:T((animator:TAnimator)T-> Unit)?T=TnullT ):TAnimator.AnimatorListenerT{T

    valTlistenerT=TobjectT:TAnimator.AnimatorListenerT{TT overrideTfunTonAnimationRepeat(animator:TAnimator)T{T onRepeat?.invoke(animator) }T overrideTfunTonAnimationEnd(animator:TAnimator)T{T onEnd?.invoke(animator) }T overrideTfunTonAnimationCancel(animator:TAnimator)T{T onCancel?.invoke(animator) }T overrideTfunTonAnimationStart(animator:TAnimator)T{T onStart?.invoke(animator)
  9. onRepeat:T((animator:TAnimator)T-> Unit)?T=TnullT ):TAnimator.AnimatorListenerT{T valTlistenerT=TobjectT:TAnimator.AnimatorListenerT{TT overrideTfunTonAnimationRepeat(animator:TAnimator)T{T onRepeat?.invoke(animator) }T overrideTfunTonAnimationEnd(animator:TAnimator)T{T onEnd?.invoke(animator) }T

    overrideTfunTonAnimationCancel(animator:TAnimator)T{T onCancel?.invoke(animator) }T overrideTfunTonAnimationStart(animator:TAnimator)T{T onStart?.invoke(animator) }T }T addListener(listener) returnTlistener }T
  10. fun Animator.addListener(T onEnd:T((animator:TAnimator)T->TUnit)?T=Tnull,T onStart:T((animator:TAnimator)T-> Unit)?T=Tnull,T onCancel:T((animator:TAnimator)T-> Unit)?T=Tnull,T onRepeat:T((animator:TAnimator)T-> Unit)?T=TnullT ):TAnimator.AnimatorListenerT{T

    valTlistenerT=TobjectT:TAnimator.AnimatorListenerT{TT overrideTfunTonAnimationRepeat(animator:TAnimator)T{T onRepeat?.invoke(animator) }T overrideTfunTonAnimationEnd(animator:TAnimator)T{T onEnd?.invoke(animator) }T overrideTfunTonAnimationCancel(animator:TAnimator)T{T onCancel?.invoke(animator) }T overrideTfunTonAnimationStart(animator:TAnimator)T{T onStart?.invoke(animator) }T }T addListener(listener) returnTlistener }T
  11. val actual = context.systemService<Type>()

  12. val actual = context.systemService<Type>() @RequiresApi(23) inline fun <reified T> Context.systemService()

    = getSystemService(T::class.java)
  13. val actual = context.systemService<Type>() @RequiresApi(23) inline fun <reified T> Context.systemService()

    = getSystemService(T::class.java)
  14. val actual = context.systemService<Type>() @RequiresApi(23) inline fun <reified T> Context.systemService()

    = getSystemService(T::class.java)
  15. val actual = context.systemService<Type>() @RequiresApi(23) inline fun <reified T> Context.systemService()

    = getSystemService(T::class.java) inline reified
  16. inline reified Body is copied over at compile time Type

    passed is preserved
  17. inline reified Body is copied over at compile time Type

    passed is preserved
  18. inline reified Body is copied over at compile time Type

    passed is preserved
  19. context.withStyledAttributes(T ... intArrayOf(android.R.attr.textColorPrimary) )T{ val resourceId = getResourceId(0, -1) ...

    }T context.withStyledAttributes(
  20. context.withStyledAttributes(…){…}T context.withStyledAttributes( inline fun Context.withStyledAttributes( ... attrs: IntArray, ... block:

    TypedArray.() -> Unit ) { val typedArray = obtainStyledAttributes(...) try { typedArray.block() } finally { typedArray.recycle() } }
  21. inline fun Context.withStyledAttributes( ... attrs: IntArray, ... block: TypedArray.() ->

    Unit ) { val typedArray = obtainStyledAttributes(...) try { typedArray.block() } finally { typedArray.recycle() } } context.withStyledAttributes(…){…}T context.withStyledAttributes(
  22. valT(a,Tr,Tg,Tb)T=T0x337f3010

  23. valT(a,Tr,Tg,Tb)T=T0x337f3010

  24. valT(a,Tr,Tg,Tb)T=T0x337f3010

  25. valT(a,Tr,Tg,Tb)T=T0x337f3010

  26. valT(a,Tr,Tg,Tb)T=T0x337f3010

  27. valT(a,Tr,Tg,Tb)T=T0x337f3010

  28. inline operator fun @receiver:ColorInt Int.component1() = (this shr 24) and

    0xff inline operator fun @receiver:ColorInt Int.component2() = (this shr 16) and 0xff inline operator fun @receiver:ColorInt Int.component3() = (this shr 8) and 0xff inline operator fun @receiver:ColorInt Int.component4() = this and 0xff valT(a,Tr,Tg,Tb)T=T0x337f3010
  29. inline operator fun @receiver:ColorInt Int.component1() = (this shr 24) and

    0xff inline operator fun @receiver:ColorInt Int.component2() = (this shr 16) and 0xff inline operator fun @receiver:ColorInt Int.component3() = (this shr 8) and 0xff inline operator fun @receiver:ColorInt Int.component4() = this and 0xff valT(a,Tr,Tg,Tb)T=T0x337f3010
  30. inline operator fun @receiver:ColorInt Int.component1() = (this shr 24) and

    0xff inline operator fun @receiver:ColorInt Int.component2() = (this shr 16) and 0xff inline operator fun @receiver:ColorInt Int.component3() = (this shr 8) and 0xff inline operator fun @receiver:ColorInt Int.component4() = this and 0xff valT(a,Tr,Tg,Tb)T=T0x337f3010
  31. inline operator fun @receiver:ColorInt Int.component1() = (this shr 24) and

    0xff inline operator fun @receiver:ColorInt Int.component2() = (this shr 16) and 0xff inline operator fun @receiver:ColorInt Int.component3() = (this shr 8) and 0xff inline operator fun @receiver:ColorInt Int.component4() = this and 0xff valT(a,Tr,Tg,Tb)T=T0x337f3010
  32. inline operator fun @receiver:ColorInt Int.component1() = (this shr 24) and

    0xff inline operator fun @receiver:ColorInt Int.component2() = (this shr 16) and 0xff inline operator fun @receiver:ColorInt Int.component3() = (this shr 8) and 0xff inline operator fun @receiver:ColorInt Int.component4() = this and 0xff valT(a,Tr,Tg,Tb)T=T0x337f3010
  33. valT(a,Tr,Tg,Tb)T=T0x337f3010 inline operator fun @receiver:ColorInt Int.component1()T= (thisTshrT24)TandT0xff inline operator fun

    @receiver:ColorInt Int.component2()T= (thisTshrT16)TandT0xff inline operator fun @receiver:ColorInt Int.component3()T= (thisTshrT8)TandT0xff inline operator fun @receiver:ColorInt Int.component4()T= thisTandT0xff
  34. valT(a,Tr,Tg,Tb)T=T0x337f3010 operatorTfun Int.component1()T= (thisTshrT24)TandT0xff operatorTfun Int.component2()T= (thisTshrT16)TandT0xff operatorTfun Int.component3()T= (thisTshrT8)TandT0xff

    operatorTfun Int.component4()T= thisTandT0xff
  35. valT(a,Tr,Tg,Tb)T=T0x337f3010 operatorTfun Int.component1() = (thisTshrT24) and 0xff operatorTfun Int.component2()T= (thisTshrT16)TandT0xff

    operatorTfun Int.component3()T= (thisTshrT8)TandT0xff operatorTfun Int.component4()T= thisTandT0xff
  36. valT(a,Tr,Tg,Tb)T=T0x337f3010 operatorTfun Int.component1() = (this shr 24) and 0xff 0x337f3010.alpha

    val Int.alpha get() = (this shr 24) and 0xff
  37. valT(a,Tr,Tg,Tb)T=T0x337f3010 operatorTfun Int.component1() = (this shr 24) and 0xff 0x337f3010.alpha

    val Int.alpha get() = (this shr 24) and 0xff
  38. valT(a,Tr,Tg,Tb)T=T0x337f3010 operatorTfun Int.component1() = (this shr 24) and 0xff 0x337f3010.alpha

    val Int.alpha get() = (this shr 24) and 0xff
  39. val path = path1 + path2

  40. val path = path1 + path2 inline operator fun Path.plus(p:

    Path): Path = Path(this).apply { op(p, Path.Op.UNION) }
  41. val path = path1 + path2 val path = path1

    and path2
  42. val path = path1 + path2 val path = path1

    and path2 inline infix fun Path.and(p: Path) = this + p
  43. varTcalledT=T0T handler.postDelayed(10)T{T called++ }T Outer scope

  44. varTcalledT=T0T handler.postDelayed(10)T{T called++ }T inline fun Handler.postDelayed( crossinline action: ()

    -> Unit) = Runnable { action() }
  45. varTcalledT=T0T handler.postDelayed(10)T{T called++ }T inline fun Handler.postDelayed( crossinline action: ()

    -> Unit) = Runnable { action() } fun foo() { ordinaryFunction { return } } ❌
  46. varTcalledT=T0T handler.postDelayed(10)T{T called++ }T inline fun Handler.postDelayed( crossinline action: ()

    -> Unit) = Runnable { action() } fun foo() { ordinaryFunction { return@ordinaryFunction } }
  47. varTcalledT=T0T handler.postDelayed(10)T{T called++ }T inline fun Handler.postDelayed( crossinline action: ()

    -> Unit) = Runnable { action() } fun foo() { ordinaryFunction f1@{ return@f1 } }
  48. varTcalledT=T0T handler.postDelayed(10)T{T called++ }T inline fun Handler.postDelayed( crossinline action: ()

    -> Unit) = Runnable { action() } fun foo() { inlineFunction { return } } ✅
  49. varTcalledT=T0T handler.postDelayed(10)T{T called++ }T inline fun Handler.postDelayed( crossinline action: ()

    -> Unit) = Runnable { action() } fun hasZeros(ints: List<Int>): Boolean { ints.forEach { if (it == 0) return true } return false }
  50. varTcalledT=T0T handler.postDelayed(10)T{T called++ }T inline fun Handler.postDelayed( crossinline action: ()

    -> Unit) = Runnable { action() }
  51. fun f1()T{T f2 {T return //ERROR return@f2 }T f3 {T

    return //f1 return@f3 }T f4 {T return //ERROR return@f4 }T }T
  52. fun f2(f: ()T-> Unit) inline fun f3(f: ()T-> Unit) inline

    fun f4(crossinline f: ()T-> Unit) fun f1()T{T f2 {T return //ERROR return@f2 }T f3 {T return //f1 return@f3 }T f4 {T return //ERROR return@f4 }T }T
  53. fun f2(f: ()T-> Unit) inline fun f3(f: ()T-> Unit) inline

    fun f4(crossinline f: ()T-> Unit) fun f1()T{T f2 {T return //ERROR return@f2 }T f3 {T return //f1 return@f3 }T f4 {T return //ERROR return@f4 }T }T
  54. fun f2(f: ()T-> Unit) inline fun f3(f: ()T-> Unit) inline

    fun f4(crossinline f: ()T-> Unit) fun f1()T{T f2 {T return //ERROR return@f2 }T f3 {T return //f1 return@f3 }T f4 {T return //ERROR return@f4 }T }T
  55. None
  56. funTshow(v:TView)T{T v.animate()T .setDuration(200)T .alphaBy(0f)T .alpha(1f)T .start()T }T

  57. funTView.show()T{T animate()T .setDuration(200)T .alphaBy(0f)T .alpha(1f)T .start()T }T

  58. funTView.show()T{T animate()T .setDuration(200)T .alphaBy(0f)T .alpha(1f)T .start()T }T funTView.hide()T{T animate()T .setDuration(200)T

    .alphaBy(1f)T .alpha(0f)T .start()T }T
  59. funTView.show()T{T animate()T .setDuration(200)T .alphaBy(0f)T .alpha(1f)T .start()T }T funTView.hide()T{T animate()T .setDuration(200)T

    .alphaBy(1f)T .alpha(0f)T .start()T }T
  60. fun View.update(T callback: ViewPropertyAnimator.()T->TViewPropertyAnimator )T{T animate()T .setDuration(200)T .callback()T .start()T }T

  61. fun View.update(T callback: ViewPropertyAnimator.()T->TViewPropertyAnimator )T{T animate()T .setDuration(200)T .callback()T .start()T }T

  62. funTView.update(T callback: ViewPropertyAnimator.()T->TViewPropertyAnimator )T{T animate()T .setDuration(200)T .callback()T .start()T }T fun

    View.show() { update { alphaBy(0f) .alpha(1f) } } funTView.hide()T{T updateT{T scaleXBy(1f) .scaleYBy(1f) .scaleX(0f) .scaleY(0f) }T }T
  63. funTView.update(T callback: ViewPropertyAnimator.()T->TViewPropertyAnimator )T{T animate()T .setDuration(200)T .callback()T .start()T }T fun

    View.show() { update { alphaBy(0f) .alpha(1f) } } funTView.hide()T{T updateT{T scaleXBy(1f) .scaleYBy(1f) .scaleX(0f) .scaleY(0f) }T }T
  64. None
  65. open.nytimes.com @nytdev github.com/NYTimes developers.nytimes.com

  66. QA & speakerdeck.com/tiwiz/inside-android-ktx