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