Google I/O 2018 にみる Android KTX その1

Android KTX は、次期 androidx のパッケージとも深い関わりをもっているようです。

androidx: Hello World!
You may notice that Android KTX uses package names that begin with androidx. This is a new package name prefix that we will be using in future versions of Android Support Library. We hope the division between android.* and androidx.* makes it more obvious which APIs are bundled with the platform, and which are static libraries for app developers that work across different versions of Android.

Android Developers Blog: Introducing Android KTX: Even Sweeter Kotlin Development for Android

また、パッケージ名に関してのマッピングも公式からアナウンスされ始めています。

AndroidX refactoring  |  Android Developers

そんな Android KTX に関係するいくつかの動画がアップされています。

Android Jetpack: sweetening Kotlin development with Android KTX (Google I/O 2018) - YouTube

Google I/O 2018: Stage 2 - YouTube

前回は、よく分からんオネーチャンが喋ってましたが、 今回は、Jake Wharton さんが遂に表に登場しました。

彼のトークやスライドは開発に有効に利用できることばかりです。

Kotlin の Extension Function の勉強にもなりますので、登場したコードを書き出しておきます。

並び順は、

「よくあるコード」(before)
「Android KTX のコード(拡張関数)」(KTX)
「KTXを利用したコード」(after)

です。

 

ViewGroupの再帰処理


// before
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...
}


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


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

 

getSystemService()


// before

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

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


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


// after
val notifications = systemService<NotificationManager>()

 

Viewのパディング


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


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


// after
avatarView.updatePadding(left = 10, right = 10)

 

デストラクチャ


// before
val rect = avaterView.clipBounds
val left = rect.left
val top = rect.top
val right = rect.right
val bottom = rect.bottom
// Use left, top, right, bottom...


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


// after
val (left, top, right, bottom) = avatarView.clipBounds
// Use left, top, right, bottom...

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

val (left, _, right) = avatarView.clipBounds
// Use left, right...

 

すべての値のチェック


// before
val onlyDigits = true
for (c in phoneNumber) {
  if (!c.isDigit()) {
    onlyDigits = false
    break
  }
}


// before
val onlyDigits = phoneNumber.all { it.isDigit() }


// before
val onlyDigits = TextUtils.isDigitsOnly(phoneNumber)


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


// after
val onlyDigits = phoneNumber.isDigitsOnly()

とりあえずは、前半のコードを書き出しておいて、次回へ

(つづく...)