Illustration by Virginia Poltrack

#31DaysOfKotlin — Week 3 Recap

The more Kotlin code we write, the more we love it! Kotlin’s modern language features together with Android KTX made our Android code more concise, clear and pleasant. We (@objcode and @FMuntenescu) started the #31DaysOfKotlin series as a way of sharing some of our favorite Kotlin and Android KTX features and hopefully get more of you to like it as much as we do.

Week 3 of Kotlin was split between Kotlin functionalities and different ways of making your Android code sweeter with Android KTX.

Check out all the recaps:

Day 15: Operator overloading

Write Kotlin (time * 2) faster with operator overloading. Objects like Path, Range or SpannableStrings naturally allow for operations like addition or subtraction. With Kotlin, you can implement your own operators. Docs: operator overloading, Android KTX usage example.

// Definition
/** Adds a span to the entire text. */
inline operator fun Spannable.plusAssign(span: Any) =
setSpan(span, 0, length, SPAN_INCLUSIVE_EXCLUSIVE)
// Use it like this
val spannable = “Eureka!!!!”.toSpannable()
spannable += StyleSpan(BOLD) // Make the text bold with +=
spannable += UnderlineSpan() // Make the text underline with +=

Day 16: Top level functions and parameters

Utility methods for a class? Add them to the top level of the source file. In Java, they are compiled as static methods of that class. Docs: basic syntax.

// Define a top-level function that creates a DataBinding Adapter for a RecyclerView
@BindingAdapter(“userItems”)
fun userItems(recyclerView: RecyclerView, list: List<User>?){
//update the RecyclerView with the new list

}
class UsersFragment: Fragment{...}

Are you defining static constants for your class? Make them top-level properties. They will be compiled to a field and static accessor(s).

// Define a top-level property for Room database
private const val DATABASE_NAME = “MyDatabase.db”
private fun makeDatabase(context: Context): MyDatabase {
return Room.databaseBuilder(
context,
MyDatabase::class.java,
DATABASE_NAME
).build()
}

Day 17: Iterating types without an iterator

Iterators in interesting places? Android KTX adds iterators to ViewGroup and SparseArray. To define iterator extensions use the operator keyword. Foreach loops will use the extensions! Docs: for loops, Android KTX usage example.

// Example from Android KTX
for(view in viewGroup) { }
for(key in sparseArray) {}
// Your project
operator Waterfall.iterator() {
// add an iterator to a waterfall class
}
for(items in myClass) {} // Now waterfall has iterations!

Day 18: Easy Content Values

Combine the power of ContentValues with the brevity of Kotlin. Use the Android KTX ContentValues creator and just pass a Pair<StringKey, Value>. Android KTX implementation.

val contentValues = contentValuesOf(
“KEY_INT” to 1,
“KEY_LONG” to 2L,
“KEY_BOOLEAN” to true,
“KEY_NULL” to null
)

Day 19: DSLs

Specifically terrific? Domain specific languages can be made by using type safe builders. They make for clean APIs; and you can build them yourself too with the help of features like extension lambdas and type safe builders.

html {
head {
title {+”This is Kotlin!” }
}
body {
h1 {+”A DSL in Kotlin!”}
p {+”It’s rather”
b {+”bold.” }
+”don’t you think?”
}
}
}

Spek is a testing library built as a Kotlin DSL. Instead of using @Annotations, Spek provides a typesafe way to declare your test code without relying on reflection magic.

@RunWith(JUnitPlatform::class)
class MyTest : Spek({
val subject = Subject()
given("it ’ s on fire") {
subject.lightAFire()
it("should be burning") {
assertTrue(subject.isBurning())
}
it("should not be cold") {
assertFalse(subject.isCold())
}
}
})

Another DSL for Kotlin on Android is Anko. Anko lets you build Android views using declarative code.

frameLayout {
button("Light a fire") {
onClick {
lightAFire()
}
}

Day 20: Easy Bundle

Bundle up, and get ready for the concise bundle creator in Android KTX. No more calls to putString, putInt, or any of their 20 friends. One call will make you a new Bundle, and it’ll even handle Arrays!

val bundle = bundleOf(
"KEY_INT " to 1,
"KEY_LONG" to 2L,
"KEY_BOOLEAN" to true,
"KEY_NULL" to null
"KEY_ARRAY" to arrayOf(1, 2)
)

Day 21: Cleaning up postDelayed

Lambdas are sweet. With last parameter call syntax, you can cleanup callbacks, Callable, and Runnable. For example, Android KTX sweetens postDelayed with a small wrapper.

// Android KTX API
fun Handler.postDelayed(
delay: Int,
token: Any? = null,
action: () -> Unit)
// Call it like this — no need for a Runnable in your code
handler.postDelayed(50) {
// pass a lambda to postDelayed
}

This week focused on a few basic Kotlin features like operators overloading, top level functions and parameters and iterators, we talked about an advanced feature: domain specific languages (DSLs) and showed how you can write more concise code when using Android KTX for content values, bundles and callbacks.

Did you already start using Kotlin? We’d love to hear what other features you found great and how you used them in your Android app.