Kotlin KTX —helper for Android

Prashant Pol
4 min readApr 29, 2020

--

PC: Android & Kotlin logos

Kotlin made Android programming simpler. Kotlin provides libraries and code syntax which helps in Android programming. On top of that Kotlin’s extension functions are really life saving things to write code neatly.

A collection of all such helper and extension function is called Kotlin ktx.

Kotlin ktx is provided with a library, which can be imported using,

repositories {
google()
}
.....
.....
dependencies {
implementation "androidx.core:core-ktx:1.2.0"
}

Along with core ktx, there are list of other ktx libraries which can be added separately as and when required, currently available ktx libraries are,

  1. Collection KTX
  2. Fragment KTX
  3. Lifecycle KTX
  4. LiveData KTX
  5. Navigation KTX
  6. Palette KTX
  7. Reactive Streams KTX
  8. Room KTX
  9. Sqlite KTX
  10. ViewModel KTX
  11. WorkManager KTX
  12. Firebase KTX
  13. PlayStore KTX

Detailed explanation of all these KTX can be found on Android KTX page.

I am going to list out few ktx functions here which I found very useful while doing day-to-day Android programming.

So let’s have a look at it.

  1. View Visibility:

Normal Kotlin way,

if(view.visibility == View.VISIBLE) {
.......
}
// Also,
view.visibility = View.GONE

This thing can be written with ktx as,

if(view.isVisible) {
.......
}
view.isVisible = false

See, how efficient and readable is this.

2. ViewGroup as a collection:

As we all know, ViewGroup is used as a container which encapsulates several views and decides its position. Adding, removing views or traversing views in viewGroup can be done as,

viewGroup.addView(view1)
viewGroup.addView(view2)
for(view in view.getChildren()) {
....
}

Better ktx has something better for doing this,

viewGroup += view
viewGroup -= view
viewGroup.forEach {
....
}
viewGroup.contains(view)
viewGroup.isEmpty()
viewGroup.isNotEmpty()

Wow, ViewGroup can be handled as a Collection.

3. View Layout change listener:

This is the best example which demonstrates how ktx helps to remove boilerplate code.

Suppose we want to do something when there is update on view’s layout, then Kotlin code for the same would be,

view.addOnLayoutChangeListener(object : View.OnLayoutChangeListener{
override fun onLayoutChange(
v: View?,
left: Int,
top: Int,
right: Int,
bottom: Int,
oldLeft: Int,
oldTop: Int,
oldRight: Int,
oldBottom: Int) {
view.removeOnLayoutChangeListener(this)
doSomething()
}
})

Here, the thing which we want to do is doSomeThing() but we have to write other several lines, also need to carefully remove listener to avoid issues.

KTX simplifies it just by writing,

view.doOnLayout { doSomething() }

That’s all.

Along with this function, we got some other similar listener ktx functions as well,

view.doOnLayout {}
view.doOnNextLayout {}
view.doOnAttach {}
view.doOnDetach {}

3. Creating bitmap from a view:

View can be captured in a bitmap as,

val bitmap = Bitmap.createBitmap(view.width, view.height,
Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
view.draw(canvas)
return bitmap

KTX alternative for the same is,

val bitmap = view.drawToBitmap()

4. SharedPreferences :

Values can be put in sharedPreferences as,

val preferences = getSharedPreferences("A", 0)
preferences.edit()
.putBoolean("Key_1", true)
.putBoolean("Key_2", false)
.putInt("Key_3", 10000)
.apply()

Here, need to commit() or apply() without fail. Same thing can be achieved by,

val preferences = getSharedPreferences("A", 0)
preferences.edit {
putBoolean("Key_1", true)
putBoolean("Key_2", false)
putInt("Key_3", 10000)
}
// Asynchronous way is preferences.edit { }// For synchronous write, use preferences.edit(commit = true) { }

5. Padding:

When updating a single padding for a view, we need to set all other padding values as well.

view.setPadding(
10,
view.paddingTop,
view.paddingRight,
view.paddingBottom
)

But ktx allows to do it as,

view.updatePadding(left = 10)

6. Animator listener:

Suppose we want to do something when animation ends, then implementation would be,

val animator = ObjectAnimator()
animator.addListener(object : Animator.AnimatorListener {
override fun onAnimationRepeat(animation: Animator?) {
} override fun onAnimationEnd(animation: Animator?) {
doSomething()
}
override fun onAnimationCancel(animation: Animator?) { } override fun onAnimationStart(animation: Animator?) { }
})

Although, we don’t want do anything on animation cancel, start or repeat but then also, need to implement its methods as well. Which is actually redundant. KTX solves it by providing,

animator.doOnStart {  }
animator.doOnRepeat { }
animator.doOnCancel { }
animator.doOnEnd { }
animator.doOnPause { }
animator.doOnResume { }

Just use what we want and no need to implement non required part.

7. TextView:

Listeners used for TextViews are provided by ktx as,

TextView.doOnTextChanged {}
TextView.doBeforeTextChanged {}
TextView.doAfterTextChanged {}

It’s very handy to use.

8. Sqlite:

While using Sqlite database, need to start transaction and then end it without fail. Otherwise it may cause disaster. So, simple kotlin code would be,

db.beginTransaction()insertData(db)db.setTransactionAsSuccessful()
db.endTransaction()

Ktx way of writing it is,

db.transaction {
insertData(db)
}

KTX handles rest of the boilerplate code.

9. FragmentManager:

Similar handy way to handle transaction is also provided for FragmentManager as well,

fragmentManager
.beginTransaction()
.replace(....)
.commit()
// KTX way
fragmentManager.commit {
replace(.....)
}

10. ViewModels:

ViewModels can be created with underlying scope as,

viewModels<MyViewModel>()

If we want to create viewModel in fragment with activity scope then it would be like,

activityViewModels<MyViewModel>()

There are plenty of other extension functions as well, I wish you to go through it and make Android programming easier by avoiding boilerplate code.

Please clap if you like it.

--

--