Anko Commons is a “toolbox” for Kotlin Android developer. The library contains a lot of helpers for Android SDK, including, but not limited to:
Using Anko Dialogs in your project
Dialog helpers are inside the anko-commons artifact. Add it as a dependency to your build.gradle:
dependencies {
compile "org.jetbrains.anko:anko-commons:$anko_version"
}
Toasts
Simply shows a Toast message.
toast("Hi there!")
toast(R.string.message)
longToast("Wow, such a duration")
Alerts
A small DSL for showing alert dialogs.
alert("Hi, I'm Roy", "Have you tried turning it off and on again?") {
yesButton { toast("Oh…") }
noButton {}
}.show()
The code above will show the default Android alert dialog. If you want to switch to the appcompat implementation, use the Appcompat dialog factory:
alert(Appcompat, "Some text message").show()
Selectors
selector() shows an alert dialog with a list of text items:
val countries = listOf("Russia", "USA", "Japan", "Australia")
selector("Where are you from?", countries) { i ->
toast("So you're living in ${countries[i]}, right?")
}
Progress dialogs
progressDialog() creates and shows a progress dialog.
val dialog = progressDialog(message = "Please wait a bit…", title = "Fetching data")
An indeterminate progress dialog is also available (see indeterminateProgressDialog()).
Intent builder functions
In general, you have to write a couple of lines to start a new Activity. And it requires you to write an additional line for each value you pass as an extra. For example, this is a code for starting an Activity with extra ("id", 5) and a special flag:
val intent = Intent(this, SomeOtherActivity::class.java)
intent.putExtra("id", 5)
intent.setFlag(Intent.FLAG_ACTIVITY_SINGLE_TOP)
startActivity(intent)
Four lines is too much for this. Anko offers you an easier way:
startActivity(intentFor<SomeOtherActivity>("id" to 5).singleTop())
Useful Intent callers
Anko has call wrappers for some widely used Intents:
| Goal | Solution |
|---|---|
| Make a call | makeCall(number) without tel: |
| Send a text | sendSMS(number, [text]) without sms: |
| Browse the web | browse(url) |
| Share some text | share(text, [subject]) |
| Send a email | email(email, [subject], [text]) |
Arguments in square brackets ([]) are optional. Methods return true if the intent was sent.
Trait-like style
Android SDK provides android.util.Log class with some logging methods. Usage is pretty straightforward though the methods require you to pass a tag argument. You can eliminate this with using AnkoLogger trait-like interface:
class SomeActivity : Activity(), AnkoLogger {
private fun someMethod() {
info("London is the capital of Great Britain")
debug(5) // .toString() method will be executed
warn(null) // "null" will be printed
}
}
| android.util.Log | AnkoLogger |
|---|---|
v() |
verbose() |
d() |
debug() |
i() |
info() |
w() |
warn() |
e() |
error() |
wtf() |
wtf() |
The default tag name is a class name (SomeActivity in this case) but you can easily change it by overriding the loggerTag property.
Each method has two versions: plain and lazy (inlined):
info("String " + "concatenation")
info { "String " + "concatenation" }
Colors
Two simple extension functions to make the code more readable.
| Function | Result |
|---|---|
0xff0000.opaque |
non-transparent red |
0x99.gray.opaque |
non-transparent #999999 gray |
Dimensions
You can specify dimension values in dip (density-independent pixels) or in sp (scale-independent pixels): dip(dipValue) or sp(spValue). Note that the textSize property already accepts sp (textSize = 16f). Use px2dip and px2sp to convert backwards.
applyRecursively()
applyRecursively() applies the lambda expression to the passed View itself, and then recursively to every child of a View if it is a ViewGroup:
verticalLayout {
editText {
hint = "Name"
}
editText {
hint = "Password"
}
}.applyRecursively { view -> when(view) {
is EditText -> view.textSize = 20f
}}
In next article we discuss about Anko Coroutines.

Share your thoughts