155
Android KTX Jake Wharton

Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

  • Upload
    others

  • View
    3

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

Android KTX

Jake Wharton

Page 2: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

Android KTX

Jake Wharton

Page 3: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index) // Do something with index and view… }

Page 4: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

fun ViewGroup.forEachIndexed(action: (Int, View) -> Unit) { for (index in 0 until childCount) { action(index, getChildAt(index)) }Z }

val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index) // Do something with index and view… }A

Page 5: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

fun ViewGroup.forEachIndexed(action: (Int, View) -> Unit) { for (index in 0 until childCount) { action(index, getChildAt(index)) }Z }

val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index) // Do something with index and view… }A

Page 6: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

fun ViewGroup.forEachIndexed(action: (Int, View) -> Unit) { for (index in 0 until childCount) { action(index, getChildAt(index)) }Z }D

val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) {G val view = userLayout.getChildAt(index) // Do something with index and view… }A

Page 7: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

fun ViewGroup.forEachIndexed(action: (Int, View) -> Unit) { for (index in 0 until childCount) { action(index, getChildAt(index)) }Z }D

val userLayout: ViewGroup = findViewById(R.id.users) userLayout.forEachIndexed {Gindex, view -> // Do something with index and view… }A

for ( in 0 until .childCount) val = userLayout.getChildAt(index)

Page 8: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

fun ViewGroup.forEachIndexed(action: (Int, View) -> Unit) { for (index in 0 until childCount) { action(index, getChildAt(index)) }Z }D

val userLayout: ViewGroup = findViewById(R.id.users) userLayout.forEachIndexed {Gindex, view -> // Do something with index and view… }A

Page 9: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

fun ViewGroup.forEachIndexed(action: (Int, View) -> Unit) { for (index in 0 until childCount) { action(index, getChildAt(index)) }Z }D

val userLayout: ViewGroup = findViewById(R.id.users) userLayout.forEachIndexed {Gindex, view -> // Do something with index and view… }A

Page 10: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun ViewGroup.forEachIndexed(action: (Int, View) -> Unit) { for (index in 0 until childCount) { action(index, getChildAt(index)) }Z }D

val userLayout: ViewGroup = findViewById(R.id.users) userLayout.forEachIndexed {Gindex, view -> // Do something with index and view… }A

Page 11: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun ViewGroup.forEachIndexed(action: (Int, View) -> Unit) { for (index in 0 until childCount) { action(index, getChildAt(index)) }Z }D

val userLayout: ViewGroup = findViewById(R.id.users) userLayout.forEachIndexed {Gindex, view -> // Do something with index and view… }A

Page 12: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

// In an Activity, on API 23+… val notifications = getSystemService(NotificationManager::class.java)

Page 13: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

// In an Activity, on API 23+… val notifications = getSystemService(NotificationManager::class.java)

// or all API levels… val notifications = ContextCompat.getSystemService(this, NotificationManager::class.java)

Page 14: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

// In an Activity, on API 23+… val notifications = getSystemService(NotificationManager::class.java)

// or all API levels… val notifications = ContextCompat.getSystemService(this, NotificationManager::class.java)

inline fun <reified T> Context.systemService() = ContextCompat.getSystemService(this, T::class.java)

Page 15: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun <reified T> Context.systemService() = ContextCompat.getSystemService(this, T::class.java)

// In an Activity, on API 23+… val notifications = getSystemService(NotificationManager::class.java)

// or all API levels… val notifications = ContextCompat.getSystemService(this, NotificationManager::class.java)

Page 16: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun <reified T> Context.systemService() = ContextCompat.getSystemService(this, T::class.java)

// In an Activity, on API 23+… val notifications = getSystemService(NotificationManager::class.java)

// or all API levels… val notifications = ContextCompat.getSystemService(this, NotificationManager::class.java)

Page 17: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun <reified T> Context.systemService() = ContextCompat.getSystemService(this, T::class.java)

// In an Activity, on API 23+… val notifications = getSystemService(NotificationManager::class.java)H

// or all API levels… val notifications = ContextCompat.getSystemService(this, NotificationManager::class.java)

s

Page 18: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun <reified T> Context.systemService() = ContextCompat.getSystemService(this, T::class.java)

// In an Activity… val notifications = systemService<NotificationManager>()H S

Page 19: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun <reified T> Context.systemService() = ContextCompat.getSystemService(this, T::class.java)

// In an Activity… val notifications = systemService<NotificationManager>()H

Page 20: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

avatarView.setPadding( 10, avatarView.paddingTop, 10, avatarView.paddingBottom)

Page 21: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun View.updatePadding( left: Int = paddingLeft, top: Int = paddingTop, right: Int = paddingRight, bottom: Int = paddingBottom ) { setPadding(left, top, right, bottom) }

avatarView.setPadding( 10, avatarView.paddingTop, 10, avatarView.paddingBottom)

Page 22: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun View.updatePadding( left: Int = paddingLeft, top: Int = paddingTop, right: Int = paddingRight, bottom: Int = paddingBottom ) { setPadding(left, top, right, bottom) }

avatarView.setPadding( 10, avatarView.paddingTop, 10, avatarView.paddingBottom)

Page 23: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun View.updatePadding( left: Int = paddingLeft, top: Int = paddingTop, right: Int = paddingRight, bottom: Int = paddingBottom ) { setPadding(left, top, right, bottom) }A

avatarView.setPadding( 10, avatarView.paddingTop, 10, avatarView.paddingBottom)R update

Page 24: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun View.updatePadding( left: Int = paddingLeft, top: Int = paddingTop, right: Int = paddingRight, bottom: Int = paddingBottom ) { setPadding(left, top, right, bottom) }A

avatarView.updatePadding(10, 10)R

Page 25: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun View.updatePadding( left: Int = paddingLeft, top: Int = paddingTop, right: Int = paddingRight, bottom: Int = paddingBottom ) { setPadding(left, top, right, bottom) }A

avatarView.updatePadding(10, 10)R

Page 26: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun View.updatePadding( left: Int = paddingLeft, top: Int = paddingTop, right: Int = paddingRight, bottom: Int = paddingBottom ) { setPadding(left, top, right, bottom) }A

avatarView.updatePadding(left = 10, right = 10)R

Page 27: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun View.updatePadding( left: Int = paddingLeft, top: Int = paddingTop, right: Int = paddingRight, bottom: Int = paddingBottom ) { setPadding(left, top, right, bottom) }A

avatarView.updatePadding(left = 10, right = 10)R

Page 28: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

val rect = avatarView.clipBounds val left = rect.left val top = rect.top val right = rect.right val bottom = rect.bottom // Use left, top, right, bottom…

Page 29: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

val rect = avatarView.clipBounds val left = rect.left val top = rect.top val right = rect.right val bottom = rect.bottom // Use left, top, right, bottom…

inline operator fun Rect.component1() = left inline operator fun Rect.component2() = top inline operator fun Rect.component3() = right inline operator fun Rect.component4() = bottom

Page 30: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline operator fun Rect.component1() = left inline operator fun Rect.component2() = top inline operator fun Rect.component3() = right inline operator fun Rect.component4() = bottom

val rect = avatarView.clipBounds val left = rect.left val top = rect.top val right = rect.right val bottom = rect.bottom // Use left, top, right, bottom…

Page 31: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline operator fun Rect.component1() = left inline operator fun Rect.component2() = top inline operator fun Rect.component3() = right inline operator fun Rect.component4() = bottom

val rect = avatarView.clipBounds val left = rect.left val top = rect.top val right = rect.right val bottom = rect.bottom // Use left, top, right, bottom…

Page 32: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline operator fun Rect.component1() = left inline operator fun Rect.component2() = top inline operator fun Rect.component3() = right inline operator fun Rect.component4() = bottom

val rect = avatarView.clipBounds val left = rect.left valTtop = rect.top valRright = rect.right valBbottom = rect.bottom // Use left, top, right, bottom…

Page 33: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline operator fun Rect.component1() = left inline operator fun Rect.component2() = top inline operator fun Rect.component3() = right inline operator fun Rect.component4() = bottom

val (left,Ttop,Rright,Bbottom) = avatarView.clipBounds // Use left, top, right, bottom…

Page 34: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline operator fun Rect.component1() = left inline operator fun Rect.component2() = top inline operator fun Rect.component3() = right inline operator fun Rect.component4() = bottom

val (left,Ttop,Rright) = avatarView.clipBounds // Use left, top, right…

Page 35: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline operator fun Rect.component1() = left inline operator fun Rect.component2() = top inline operator fun Rect.component3() = right inline operator fun Rect.component4() = bottom

val (left,T_,Rright) = avatarView.clipBounds // Use left, right…

Page 36: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline operator fun Rect.component1() = left inline operator fun Rect.component2() = top inline operator fun Rect.component3() = right inline operator fun Rect.component4() = bottom

val (left,T_,Rright) = avatarView.clipBounds // Use left, right…

Page 37: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

var onlyDigits = true for (c in phoneNumber) {A if (!c.isDigit()) { onlyDigits = false break }G }B

Page 38: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

r true for (c in ) if (!c. ) { onlyDigits = false break }G

val onlyDigits = phoneNumber.all {Ait.isDigit() }B

Page 39: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

.all {Ait.isDigit() }Bval onlyDigits = TextUtils.isDigitsOnly(phoneNumber)

Page 40: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun CharSequence.isDigitsOnly() = TextUtils.isDigitsOnly(this)Z

val onlyDigits = TextUtils.isDigitsOnly(phoneNumber)L

Page 41: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun CharSequence.isDigitsOnly() = TextUtils.isDigitsOnly(this)Z

val onlyDigits = phoneNumber.isDigitsOnly()L

Page 42: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun CharSequence.isDigitsOnly() = TextUtils.isDigitsOnly(this)Z

val onlyDigits = phoneNumber.

Page 43: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun CharSequence.isDigitsOnly() = TextUtils.isDigitsOnly(this)Z

val onlyDigits = phoneNumber.

Page 44: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun CharSequence.isDigitsOnly() = TextUtils.isDigitsOnly(this)Z

val onlyDigits = phoneNumber.is

Page 45: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun CharSequence.isDigitsOnly() = TextUtils.isDigitsOnly(this)Z

val onlyDigits = phoneNumber.is

Page 46: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun CharSequence.isDigitsOnly() = TextUtils.isDigitsOnly(this)Z

val onlyDigits = phoneNumber.isDigitsOnly()L

Page 47: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun ViewGroup.forEachIndexed(action: (Int, View) -> Unit) { for (index in 0 until childCount) { action(index, getChildAt(index)) }Z }

inline fun <reified T> Context.systemService() = ContextCompat.getSystemService(this, T::class.java)

inline fun View.updatePadding( left: Int = paddingLeft, top: Int = paddingTop, right: Int = paddingRight, bottom: Int = paddingBottom ) { setPadding(left, top, right, bottom) }

inline operator fun Rect.component1() = left inline operator fun Rect.component2() = top inline operator fun Rect.component3() = right inline operator fun Rect.component4() = bottom

inline fun CharSequence.isDigitsOnly() = TextUtils.isDigitsOnly(this)Z

Page 48: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)
Page 49: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

core-ktx

Android KTX

Page 50: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

Android KTXcore-ktx Android framework

Page 51: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

Android KTXAndroid frameworksupport-compatcore-ktx

Page 52: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

Android KTXAndroid frameworkcorecore-ktx

Page 53: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

Android KTXAndroid frameworkcorecore-ktx

fragment-ktx fragment

palette-ktx palette

collection-ktx collection

lifecycle-reactivestreams-ktx lifecycle-reactivestreams

sqlite-ktx sqlite

navigation-*-ktx navigation-*

work-runtime-ktx work-runtime

Page 54: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

Android KTXAndroid frameworkcorecore-ktx

fragment-ktx fragment

palette-ktx palette

collection-ktx collection

lifecycle-reactivestreams-ktx lifecycle-reactivestreams

sqlite-ktx sqlite

navigation-*-ktx navigation-*

work-runtime-ktx work-runtime

Page 55: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

@RequiresApi(26) operator fun Color.plus(c: Color): Color { val s = if (colorSpace != c.colorSpace) c.convert(colorSpace) else c

val src = s.components val dst = components

var sa = s.alpha() // Destination alpha pre-composited var da = alpha() * (1.0f - sa)

// Index of the alpha component val ai = componentCount - 1

// Final alpha: src_alpha + dst_alpha * (1 - src_alpha) dst[ai] = sa + da

// Divide by final alpha to return non pre-multiplied color if (dst[ai] > 0) { sa /= dst[ai] da /= dst[ai] }

// Composite non-alpha components for (i in 0 until ai) { dst[i] = src[i] * sa + dst[i] * da }

return Color.valueOf(dst, colorSpace) }

Page 56: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

@RequiresApi(26) operator fun Color.plus(c: Color): Color { val s = if (colorSpace != c.colorSpace) c.convert(colorSpace) else c

val src = s.components val dst = components

var sa = s.alpha() // Destination alpha pre-composited var da = alpha() * (1.0f - sa)

// Index of the alpha component val ai = componentCount - 1

// Final alpha: src_alpha + dst_alpha * (1 - src_alpha) dst[ai] = sa + da

// Divide by final alpha to return non pre-multiplied color if (dst[ai] > 0) { sa /= dst[ai] da /= dst[ai] }

// Composite non-alpha components for (i in 0 until ai) { dst[i] = src[i] * sa + dst[i] * da }

return Color.valueOf(dst, colorSpace) }

Page 57: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

@RequiresApi(26) operator fun Color.plus(c: Color): Color { val s = if (colorSpace != c.colorSpace) c.convert(colorSpace) else c

val src = s.components val dst = components

var sa = s.alpha() // Destination alpha pre-composited var da = alpha() * (1.0f - sa)

// Index of the alpha component val ai = componentCount - 1

// Final alpha: src_alpha + dst_alpha * (1 - src_alpha) dst[ai] = sa + da

// Divide by final alpha to return non pre-multiplied color if (dst[ai] > 0) { sa /= dst[ai] da /= dst[ai] }

// Composite non-alpha components for (i in 0 until ai) { dst[i] = src[i] * sa + dst[i] * da }

return Color.valueOf(dst, colorSpace) }

Page 58: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

public final class ColorUtils { }Z

Page 59: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

public final class ColorUtils { @ColorInt public static int compositeColors( @ColorInt int foreground, @ColorInt int background) { // … }X }Z

Page 60: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

public final class ColorUtils { @ColorInt public static int compositeColors( @ColorInt int foreground, @ColorInt int background) { // … }X

@RequiresApi(26) public static Color compositeColors( Color foreground, Color background) { // … }Y }Z

Page 61: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

@RequiresApi(26) operator fun Color.plus(c: Color): Color { val s = if (colorSpace != c.colorSpace) c.convert(colorSpace) else c

val src = s.components val dst = components

var sa = s.alpha() // Destination alpha pre-composited var da = alpha() * (1.0f - sa)

// Index of the alpha component val ai = componentCount - 1

// Final alpha: src_alpha + dst_alpha * (1 - src_alpha) dst[ai] = sa + da

// Divide by final alpha to return non pre-multiplied color if (dst[ai] > 0) { sa /= dst[ai] da /= dst[ai] }

// Composite non-alpha components for (i in 0 until ai) { dst[i] = src[i] * sa + dst[i] * da }

return Color.valueOf(dst, colorSpace) }

Page 62: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

@RequiresApi(26) inline operator fun Color.plus(c: Color): Color = ColorUtils.compositeColors(c, this)

Page 63: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun ViewGroup.forEachIndexed(action: (Int, View) -> Unit) { for (index in 0 until childCount) { action(index, getChildAt(index)) }Z }

inline fun <reified T> Context.systemService() = ContextCompat.getSystemService(this, T::class.java)

inline fun View.updatePadding( left: Int = paddingLeft, top: Int = paddingTop, right: Int = paddingRight, bottom: Int = paddingBottom ) { setPadding(left, top, right, bottom) }

inline operator fun Rect.component1() = left inline operator fun Rect.component2() = top inline operator fun Rect.component3() = right inline operator fun Rect.component4() = bottom

inline fun CharSequence.isDigitsOnly() = TextUtils.isDigitsOnly(this)Z

Page 64: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun ViewGroup.forEachIndexed(action: (Int, View) -> Unit) { for (index in 0 until childCount) { action(index, getChildAt(index)) }Z }

inline fun <reified T> Context.systemService() = ContextCompat.getSystemService(this, T::class.java)

inline fun View.updatePadding( left: Int = paddingLeft, top: Int = paddingTop, right: Int = paddingRight, bottom: Int = paddingBottom ) { setPadding(left, top, right, bottom) }

inline operator fun Rect.component1() = left inline operator fun Rect.component2() = top inline operator fun Rect.component3() = right inline operator fun Rect.component4() = bottom

inline fun CharSequence.isDigitsOnly() = TextUtils.isDigitsOnly(this)Z

Page 65: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

KTX Principles

Page 66: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

KTX Principles

Adapt existing functionality and redirect features upstream

Page 67: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun ViewGroup.forEachIndexed(action: (Int, View) -> Unit) { for (index in 0 until childCount) { action(index, getChildAt(index)) }Z }

inline fun <reified T> Context.systemService() = ContextCompat.getSystemService(this, T::class.java)

inline fun View.updatePadding( left: Int = paddingLeft, top: Int = paddingTop, right: Int = paddingRight, bottom: Int = paddingBottom ) { setPadding(left, top, right, bottom) }

inline operator fun Rect.component1() = left inline operator fun Rect.component2() = top inline operator fun Rect.component3() = right inline operator fun Rect.component4() = bottom

inline fun CharSequence.isDigitsOnly() = TextUtils.isDigitsOnly(this)Z

Page 68: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun ViewGroup.forEachIndexed(action: (Int, View) -> Unit) { for (index in 0 until childCount) { action(index, getChildAt(index)) }Z }

inline fun <reified T> Context.systemService() = ContextCompat.getSystemService(this, T::class.java)

inline fun View.updatePadding( left: Int = paddingLeft, top: Int = paddingTop, right: Int = paddingRight, bottom: Int = paddingBottom ) { setPadding(left, top, right, bottom) }

inline operator fun Rect.component1() = left inline operator fun Rect.component2() = top inline operator fun Rect.component3() = right inline operator fun Rect.component4() = bottom

inline fun CharSequence.isDigitsOnly() = TextUtils.isDigitsOnly(this)Z

Page 69: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun ViewGroup.forEachIndexed(action: (Int, View) -> Unit) { for (index in 0 until childCount) { action(index, getChildAt(index)) }Z }

inline fun <reified T> Context.systemService() = ContextCompat.getSystemService(this, T::class.java)

inline fun View.updatePadding( left: Int = paddingLeft, top: Int = paddingTop, right: Int = paddingRight, bottom: Int = paddingBottom ) { setPadding(left, top, right, bottom) }

inline operator fun Rect.component1() = left inline operator fun Rect.component2() = top inline operator fun Rect.component3() = right inline operator fun Rect.component4() = bottom

inline fun CharSequence.isDigitsOnly() = TextUtils.isDigitsOnly(this)Z

Page 70: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

operator fun ViewGroup.iterator() = object : MutableIterator<View> { private var index = 0 override fun hasNext() = index < childCount override fun next() = getChildAt(index++) ?: throw IndexOutOfBoundsException() override fun remove() = removeViewAt(--index) }

Page 71: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

operator fun ViewGroup.iterator() = object : MutableIterator<View> { private var index = 0 override fun hasNext() = index < childCount override fun next() = getChildAt(index++) ?: throw IndexOutOfBoundsException() override fun remove() = removeViewAt(--index) }

for (view in userLayout) { // Do something with view… }

Page 72: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

operator fun ViewGroup.iterator() = object : MutableIterator<View> { private var index = 0 override fun hasNext() = index < childCount override fun next() = getChildAt(index++) ?: throw IndexOutOfBoundsException() override fun remove() = removeViewAt(--index) }

for (view in userLayout) { // Do something with view… }

Page 73: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

operator fun ViewGroup.iterator() = object : MutableIterator<View> { private var index = 0 override fun hasNext() = index < childCount override fun next() = getChildAt(index++) ?: throw IndexOutOfBoundsException() override fun remove() = removeViewAt(--index) }

for (view in userLayout) { // Do something with view… }

Page 74: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

KTX Principles

Adapt existing functionality and redirect features upstream

Page 75: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

KTX Principles

Adapt existing functionality and redirect features upstream

Default to inline unless code size or allocation is prohibitive

Page 76: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun ViewGroup.forEachIndexed(action: (Int, View) -> Unit) { for (index in 0 until childCount) { action(index, getChildAt(index)) }Z }Z

val userLayout: ViewGroup = findViewById(R.id.users) userLayout.forEachIndexed { index, view -> // Do something with index and view… }A

Page 77: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun <reified T> Context.systemService() = ContextCompat.getSystemService(this, T::class.java)

// In an Activity… val notifications = systemService<NotificationManager>()H

Page 78: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun View.updatePadding( left: Int = paddingLeft, top: Int = paddingTop, right: Int = paddingRight, bottom: Int = paddingBottom ) { setPadding(left, top, right, bottom) }A

avatarView.updatePadding(left = 10, right = 10)R

Page 79: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline operator fun Rect.component1() = left inline operator fun Rect.component2() = top inline operator fun Rect.component3() = right inline operator fun Rect.component4() = bottom

val (left,T_,Rright) = avatarView.clipBounds // Use left, right…

Page 80: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun CharSequence.isDigitsOnly() = TextUtils.isDigitsOnly(this)Z

val onlyDigits = phoneNumber.isDigitsOnly()L

Page 81: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

operator fun ViewGroup.iterator() = object : MutableIterator<View> { private var index = 0 override fun hasNext() = index < childCount override fun next() = getChildAt(index++) ?: throw IndexOutOfBoundsException() override fun remove() = removeViewAt(--index) }

for (view in userLayout) { // Do something with view… }

Page 82: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

KTX Principles

Adapt existing functionality and redirect features upstream

Default to inline unless code size or allocation is prohibitive

Page 83: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

KTX Principles

Adapt existing functionality and redirect features upstream

Default to inline unless code size or allocation is prohibitive

Leverage features unique to Kotlin

Page 84: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

view.setOnClickListener { // React to click… }Z

Page 85: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

fun View.click(listener: (View) -> Unit) { setOnClickListener(listener) }Y

view.setOnClickListener {P // React to click… }Z

Page 86: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

fun View.click(listener: (View) -> Unit) { setOnClickListener(listener) }Y

view.setOnClickListener {P // React to click… }Z

c

Page 87: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

fun View.click(listener: (View) -> Unit) { setOnClickListener(listener) }Y

view.click {P // React to click… }Z

C

Page 88: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

view.click {P // React to click… }Z

view.setOnClickListener { // React to click… }

Page 89: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

KTX Principles

Adapt existing functionality and redirect features upstream

Default to inline unless code size or allocation is prohibitive

Leverage features unique to Kotlin

Page 90: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

KTX Principles

Adapt existing functionality and redirect features upstream

Default to inline unless code size or allocation is prohibitive

Leverage features unique to Kotlin

Code golf APIs to be as short as possible

Page 91: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

if (Build.VERSION.SDK_INT >= 19) { TransitionManager.beginDelayedTransition(viewGroup) }Z

Page 92: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun onApi(level: Int, body: () -> Unit) { if (Build.VERSION.SDK_INT >= level) { body() }Z }

if (Build.VERSION.SDK_INT > 19) { TransitionManager.beginDelayedTransition(viewGroup) }Z

Page 93: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun onApi(level: Int, body: () -> Unit) { if (Build.VERSION.SDK_INT >= level) { body() }Z }Q

if (Build.VERSION.SDK_INT > 19) { TransitionManager.beginDelayedTransition(viewGroup) }Z

onApi

Page 94: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun onApi(level: Int, body: () -> Unit) { if (Build.VERSION.SDK_INT >= level) { body() }Z }Q

onApi(19) { TransitionManager.beginDelayedTransition(viewGroup) }Z

Page 95: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

onApi(19) { TransitionManager.beginDelayedTransition(viewGroup) }Z

Page 96: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

onApi(19) { TransitionManager.beginDelayedTransition(viewGroup) }Z

if (Build.VERSION.SDK_INT >= 19) { TransitionManager.beginDelayedTransition(viewGroup) }Z

Page 97: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

if (SDK_INT >= 19) { TransitionManager.beginDelayedTransition(viewGroup) }Z

onApi(19) { TransitionManager.beginDelayedTransition(viewGroup) }Z

Page 98: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

if (SDK_INT >= 19) { TransitionManager.beginDelayedTransition(viewGroup) }Z

onApi(19) { TransitionManager.beginDelayedTransition(viewGroup) }Z

Page 99: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

if (SDK_INT >= 19) { TransitionManager.beginDelayedTransition(viewGroup) }Zelse { // Something… }

onApi(19) { TransitionManager.beginDelayedTransition(viewGroup) }Z

Page 100: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

if (SDK_INT >= 19) { TransitionManager.beginDelayedTransition(viewGroup) }Zelse { // Something… }L

onApi(19)F{A TransitionManager.beginDelayedTransition(viewGroup) },

Page 101: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

if (SDK_INT >= 19) { TransitionManager.beginDelayedTransition(viewGroup) }Zelse { // Something… }L

onApi(19, {A TransitionManager.beginDelayedTransition(viewGroup) }, {T // Something… })F

Page 102: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

if (SDK_INT >= 28) { // Fancy new thing… } else if (SDK_INT >= 19) { TransitionManager.beginDelayedTransition(viewGroup) }Zelse { // Something… }L

onApi(19, {A TransitionManager.beginDelayedTransition(viewGroup) },Z{T // Something… })F

Page 103: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

if (SDK_INT >= 28) { // Fancy new thing… } else if (SDK_INT >= 19) { TransitionManager.beginDelayedTransition(viewGroup) }Zelse { // Something… }L

onApi(19, {A TransitionManager.beginDelayedTransition(viewGroup) },Z{T // Something… })F

Page 104: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

KTX Principles

Adapt existing functionality and redirect features upstream

Default to inline unless code size or allocation is prohibitive

Leverage features unique to Kotlin

Code golf APIs to be as short as possible

Page 105: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

KTX Principles

Adapt existing functionality and redirect features upstream

Default to inline unless code size or allocation is prohibitive

Leverage features unique to Kotlin

Code golf APIs to be as short as possible

Optimize for a single and/or specific use case

Page 106: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

Android KTXAndroid frameworkcorecore-ktx

fragment-ktx fragment

palette-ktx palette

collection-ktx collection

lifecycle-reactivestreams-ktx lifecycle-reactivestreams

sqlite-ktx sqlite

navigation-*-ktx navigation-*

work-runtime-ktx work-runtime

Page 107: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

Android KTXAndroid frameworkcorecore-ktx

fragment-ktx fragment

palette-ktx palette

collection-ktx collection

lifecycle-reactivestreams-ktx lifecycle-reactivestreams

sqlite-ktx sqlite

navigation-*-ktx navigation-*

work-runtime-ktx work-runtime

Page 108: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

supportFragmentManager.beginTransaction() .replace(android.R.id.content, userFragment) .commit()

Page 109: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun FragmentManager.transaction( body: FragmentTransaction.() -> Unit ) { val transaction = beginTransaction() transaction.body() transaction.commit() }

supportFragmentManager.beginTransaction() .replace(android.R.id.content, userFragment) .commit()

Page 110: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun FragmentManager.transaction( body: FragmentTransaction.() -> Unit ) { val transaction = beginTransaction() transaction.body() transaction.commit() }A

supportFragmentManager.beginTransaction() .replace(android.R.id.content, userFragment) t

.commit()

Page 111: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun FragmentManager.transaction( body: FragmentTransaction.() -> Unit ) { val transaction = beginTransaction() transaction.body() transaction.commit() }A

supportFragmentManager.transaction { replace(android.R.id.content, userFragment) }Z

T

Page 112: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun FragmentManager.transaction( allowStateLoss: Boolean = false body: FragmentTransaction.() -> Unit ) { val transaction = beginTransaction() transaction.body() if (allowStateLoss) transaction.commitAllowingStateLoss() else transaction.commit() }A

supportFragmentManager.transaction { replace(android.R.id.content, userFragment) }Z

Page 113: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun FragmentManager.transaction( allowStateLoss: Boolean = false body: FragmentTransaction.() -> Unit ) { val transaction = beginTransaction() transaction.body() if (allowStateLoss) transaction.commitAllowingStateLoss() else transaction.commit() }A

supportFragmentManager.transaction {G replace(android.R.id.content, userFragment) }Z

Page 114: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun FragmentManager.transaction( allowStateLoss: Boolean = false, body: FragmentTransaction.() -> Unit ) { val transaction = beginTransaction() transaction.body() if (allowStateLoss) transaction.commitAllowingStateLoss() else transaction.commit() }A

supportFragmentManager.transaction(allowStateLoss = true) {G replace(android.R.id.content, userFragment) }Z

Page 115: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

L7 ALOAD 3 INVOKEVIRTUAL androidx/fragment/app/FragmentManager beginTransaction() Landroidx/fragment/app/FragmentTransaction; ASTORE 7

L8 ALOAD 7 LDC 16908290 ALOAD 2 INVOKEVIRTUAL androidx/fragment/app/FragmentTransaction replace( I Landroidx/fragment/app/Fragment; ) Landroidx/fragment/app/FragmentTransaction; POP

L9 ALOAD 7 INVOKEVIRTUAL androidx/fragment/app/FragmentTransaction commitAllowingStateLoss() I POP

Page 116: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun FragmentManager.transaction( allowStateLoss: Boolean = false, body: FragmentTransaction.() -> Unit ) { val transaction = beginTransaction() transaction.body() if (allowStateLoss) transaction.commitAllowingStateLoss() else transaction.commit() }A

supportFragmentManager.transaction(allowStateLoss = true) {G replace(android.R.id.content, userFragment) }Z

Page 117: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun FragmentManager.transaction( now: Boolean = false, allowStateLoss: Boolean = false, body: FragmentTransaction.() -> Unit ) { val transaction = beginTransaction() transaction.body() if (now) { if (allowStateLoss) transaction.commitNowAllowingStateLoss() else transaction.commitNow() } else { if (allowStateLoss) transaction.commitAllowingStateLoss() else transaction.commit() } }A

Page 118: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)
Page 119: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)
Page 120: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)
Page 121: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)
Page 122: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

Building Kotlin-friendly libraries

Page 123: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

Building Kotlin-friendly libraries

• Port public API or entire library to Kotlin

Page 124: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

Building Kotlin-friendly libraries

• Port public API or entire library to Kotlin

• Ship sibling artifact with Kotlin extensions

Page 125: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

Building Kotlin-friendly libraries

• Port public API or entire library to Kotlin

• Ship sibling artifact with Kotlin extensions

• ???

Page 126: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun CharSequence.isDigitsOnly() = TextUtils.isDigitsOnly(this)

val onlyDigits = phoneNumber.isDigitsOnly()

Page 127: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

class TextUtils { static boolean isDigitsOnly(CharSequence str) { int len = str.length(); // … }Y }Z

inline fun CharSequence.isDigitsOnly() = TextUtils.isDigitsOnly(this)

val onlyDigits = phoneNumber.isDigitsOnly()

Page 128: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

class TextUtils { static boolean isDigitsOnly(@NonNull CharSequence str) { int len = str.length(); // … }Y }Z

inline fun CharSequence.isDigitsOnly() = TextUtils.isDigitsOnly(this)

val onlyDigits = phoneNumber.isDigitsOnly()

Page 129: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

class TextUtils { static boolean isDigitsOnly(@NonNull CharSequence str) { int len = str.length(); // … }Y }Z

inline fun CharSequence.isDigitsOnly() = TextUtils.isDigitsOnly(this)

val onlyDigits = phoneNumber.isDigitsOnly()

Page 130: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

class TextUtils { @ExtensionFunction static boolean isDigitsOnly(@NonNull CharSequence str) { int len = str.length(); // … }Y }Z

inline fun CharSequence.isDigitsOnly() = TextUtils.isDigitsOnly(this)

val onlyDigits = phoneNumber.isDigitsOnly()

Page 131: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

class TextUtils { @ExtensionFunction static boolean isDigitsOnly(@NonNull CharSequence str) { int len = str.length(); // … }Y }Z

inline fun CharSequence.isDigitsOnly() = TextUtils.isDigitsOnly(this)

val onlyDigits = phoneNumber.isDigitsOnly()

Page 132: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

class TextUtils { @ExtensionFunction static boolean isDigitsOnly(@NonNull CharSequence str) { int len = str.length(); // … }Y }Z

val onlyDigits = phoneNumber.isDigitsOnly()

Page 133: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

class TextUtils { @ExtensionFunction static boolean isDigitsOnly(@NonNull CharSequence str) { int len = str.length(); // … }Y }Z

val onlyDigits = phoneNumber.isDigitsOnly()

Page 134: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

class TextUtils { @ExtensionFunction static boolean isDigitsOnly(@NonNull CharSequence str) { int len = str.length(); // … }Y }Z

val onlyDigits = phoneNumber.isDigitsOnly() // in the bytecode we get val onlyDigits = TextUtils.isDigitsOnly(phoneNumber)

Page 135: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun View.updatePadding( left: Int = paddingLeft, top: Int = paddingTop, right: Int = paddingRight, bottom: Int = paddingBottom ) { setPadding(left, top, right, bottom) }A

avatarView.updatePadding(left = 10, right = 10)R

Page 136: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

inline fun View.updatePadding( left: Int = paddingLeft, top: Int = paddingTop, right: Int = paddingRight, bottom: Int = paddingBottom ) { setPadding(left, top, right, bottom) }A

avatarView.updatePadding(left = 10, right = 10)R

Page 137: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

class View { void setPadding(int left, int top, int right, int bottom) { /* … */ }B }A

inline fun View.updatePadding( left: Int = paddingLeft, top: Int = paddingTop, right: Int = paddingRight, bottom: Int = paddingBottom ) { setPadding(left, top, right, bottom) }A

avatarView.updatePadding(left = 10, right = 10)R

Page 138: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

class View { void setPadding( @KtName("left")Aint left, @KtName("top")Aint top, @KtName("right")Aint right, @KtName("bottom")Aint bottom ) { /* … */ }B }A

inline fun View.updatePadding( left: Int = paddingLeft, top: Int = paddingTop, right: Int = paddingRight, bottom: Int = paddingBottom ) { setPadding(left, top, right, bottom) }A

Page 139: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

class View { void setPadding( @KtName("left")A@DefaultValue("paddingLeft") int left, @KtName("top")A@DefaultValue("paddingTop") int top, @KtName("right")A@DefaultValue("paddingRight") int right, @KtName("bottom")A@DefaultValue("paddingBottom") int bottom ) { /* … */ }B }A

inline fun View.updatePadding( left: Int = paddingLeft, top: Int = paddingTop, right: Int = paddingRight, bottom: Int = paddingBottom ) { setPadding(left, top, right, bottom) }A

Page 140: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

class View { void setPadding( @KtName("left") @DefaultValue("paddingLeft") int left, @KtName("top") @DefaultValue("paddingTop") int top, @KtName("right") @DefaultValue("paddingRight") int right, @KtName("bottom") @DefaultValue("paddingBottom") int bottom ) { /* … */ }B }A

avatarView.updatePadding(left = 10, right = 10)R

Page 141: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

class View { void setPadding( @KtName("left") @DefaultValue("paddingLeft") int left, @KtName("top") @DefaultValue("paddingTop") int top, @KtName("right") @DefaultValue("paddingRight") int right, @KtName("bottom") @DefaultValue("paddingBottom") int bottom ) { /* … */ }B }A

avatarView.setPadding(left = 10, right = 10)R update

Page 142: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

class View { void setPadding( @KtName("left") @DefaultValue("paddingLeft") int left, @KtName("top") @DefaultValue("paddingTop") int top, @KtName("right") @DefaultValue("paddingRight") int right, @KtName("bottom") @DefaultValue("paddingBottom") int bottom ) { /* … */ }B }A

avatarView.setPadding(left = 10, right = 10)R // in bytecode we get avatarView.setPadding( 10, avatarView.paddingTop, 10, avatarView.paddingBottom)

update

Page 143: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

KEEP-110

Page 144: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

KEEP-110

• @ExtensionFunction / @ExtensionProperty — Turn a static

method with at least one argument into an extension function or an

extension property.

Page 145: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

KEEP-110

• @ExtensionFunction / @ExtensionProperty — Turn a static

method with at least one argument into an extension function or an

extension property.

• @DefaultValue — Default parameter values.

Page 146: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

KEEP-110

• @ExtensionFunction / @ExtensionProperty — Turn a static

method with at least one argument into an extension function or an

extension property.

• @DefaultValue — Default parameter values.

• @KtName — An alternate name for methods, fields, and parameters for

use by Kotlin code.

Page 147: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

Building Kotlin-friendly libraries

• Port public API or entire library to Kotlin

• Ship sibling artifact with Kotlin extensions

• ???

Page 148: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

Building Kotlin-friendly libraries

• Port public API or entire library to Kotlin

• Ship sibling artifact with Kotlin extensions

• KEEP-110 annotations

Page 149: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

Android KTXAndroid frameworkcorecore-ktx

fragment-ktx fragment

palette-ktx palette

collection-ktx collection

lifecycle-reactivestreams-ktx lifecycle-reactivestreams

sqlite-ktx sqlite

navigation-*-ktx navigation-*

work-runtime-ktx work-runtime

Page 150: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)
Page 151: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)
Page 152: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)
Page 153: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)
Page 154: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

https://github.com/Kotlin/KEEP/issues/110

Page 155: Android KTXAndroid KTX Jake Wharton. Android KTX Jake Wharton. val userLayout: ViewGroup = findViewById(R.id.users) for (index in 0 until userLayout.childCount) { val view = userLayout.getChildAt(index)

Jake Wharton

Thank you

@JakeWharton