Open In App

Kotlin Android Extensions

Improve
Improve
Like Article
Like
Save
Share
Report

If you’ve been developing Android Apps for some time, you’re probably already tired of working with findViewById in your day-to-day life to recover views. Or maybe you gave up and started using the famous Butterknife library. If that’s your case, then you’ll love Kotlin Android Extensions. Kotlin has a built-in view injection for Android, allowing to skip manual binding or need for frameworks such as ButterKnife. Some of the advantages are a nicer syntax, better static typing, and thus being less error-prone. In your project-local (not top-level) build.gradle append extensions plugin declaration below your Kotlin plugin, on top-level indentation level.

buildscript {
...
}
id : "com.android.application"
...
id: "kotlin-android"
id "kotlin-android-extensions"
...

Using Views

Assuming we have an activity with an example layout called activity_main.xml:

XML




<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <Button
        android:id="@+id/my_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="My button"/>
</LinearLayout>


We can use Kotlin extensions to call the button without any additional binding like so:

Kotlin




import kotlinx.android.synthetic.main.activity_main.my_button
 
class MainActivity: Activity() {
  override fun onCreate(savedInstanceBundle: Bundle?) {
    super.onCreate(savedInstanceBundle)
    setContentView(R.layout.activity_main)
    // my_button is already casted
    // to a proper type of "Button"
    // instead of being a "View"
    my_button.setText("Kotlin rocks!")
   }
}


You can also import all ids appearing in layout with a * notation

// my_button can be used the same way as before

import kotlinx.android.synthetic.main.activity_main.*

Synthetic views can’t be used outside of Activities/Fragments/Views with that layout inflated:

Kotlin




import kotlinx.android.synthetic.main.activity_main.my_button
 
class NotAView {
  init {
    // This sample won't compile!
    my_button.setText("Kotlin rocks!")
  }
}


Product flavors

Android extensions also work with multiple Android Product Flavors. For example, if we have flavors in the build.gradle like so:

android {
  productFlavors {
    paid {
    ...
    }
    free {
    ...
    }
  }
}

And for example, only the free flavor has a buy button:

XML




<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">
  <Button
    android:id="@+id/buy_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Buy full version"/>
</LinearLayout>


We can bind to the flavor specifically:

import kotlinx.android.synthetic.free.main_activity.buy_button

Painful listener for getting noticed, when the view is completely drawn now is so simple and awesome with Kotlin’s extension

mView.afterMeasured {
// inside this block the view is completely drawn
// you can get view's height/width, it.height / it.width
}

Under the Hood

Kotlin




inline fun View.afterMeasured(crossinline f: View.() -> Unit) {
  viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
    override fun onGlobalLayout() {
     if (measuredHeight > 0 && measuredWidth > 0) {
       viewTreeObserver.removeOnGlobalLayoutListener(this)
       f()
     }
   }
 })
}




Last Updated : 30 May, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads