Anko
AnkoとはJetBrainsが開発を行っている、Android向けのKotlinライブラリです。
Android開発を楽にするための機能を色々持っているのですが、今回はその中でもUI構築のDSL(DomainSpecificLanguage)を中心に試してみます。
通常AndroidでUI定義はXMLで行いますが、Ankoによりコードで、それも簡潔に、記述できるようになります。
なお本稿の内容は次の環境に依ります。
- Android Studio 2.3
- Kotlin 1.0.6
プロジェクトでKotlinを有効にする方法についてはコチラ:KotlinでAndroid開発!【環境構築】
Why Anko?
そもそもなぜUI構築にAnkoを用いたいのでしょうか。
公式のドキュメントには以下の理由(XMLの問題点)が挙げられています。(意訳)
- 型安全、null安全ではない
- 各レイアウトに同じような記述を繰り返す必要がある
- XMLのparseによりパフォーマンスが下がる
- 再利用性ないじゃん?
しかし、Androidの標準機能内でコードベースのUIを定義するのは直感的でなく、構造もわかりづらく、メンテしづらいわで辛さしかありません。
そこでDSLにより簡潔に記述できるようにしてくれるのがAnkoなのです。
ライブラリの導入
プロジェクトにAnkoライブラリを導入します。
app/build.gradleに次を追記しましょう。
dependencies {
compile 'com.android.support:appcompat-v7:24.2.1'
...
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
compile "org.jetbrains.anko:anko-sdk21:0.9.1" //必須
compile "org.jetbrains.anko:anko-appcompat-v7:0.9.1"
}
メインはorg.jetbrains.anko:anko-sdkXXです。サポートライブラリを導入している場合は対応するAnkoライブラリも入れてください。
なおメインのライブラリはminSdkVersionに基づいて決まります。
15 <= minSdkVersion < 19の場合anko-sdk15
19 <= minSdkVersion < 21の場合anko-sdk19
21 <= minSdkVersion < 23の場合anko-sdk21
23 <= minSdkVersion の場合anko-sdk23
自身のプロジェクトに応じて選択してください。
追記できたらbuild.gradleをSyncしましょう。
基本的な使い方
それでは基本的な使い方を見ていきましょう。
Activityの場合はonCreateに記述することでsetContentViewを呼ばなくとも自動的にViewが適用されます。
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
verticalLayout {
textView("Hello")
}
}
}
verticalLayoutはLinearLayoutのorientation属性がverticalの要素です。
また、次のようにUIクラスを分けて定義することも可能です。
class FooActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
FooActivityUi().setContentView(this)
}
}
class FooActivityUi: AnkoComponent<FooActivity> {
override fun createView(ui: AnkoContext<FooActivity>) = with(ui) {
verticalLayout {
textView("Hello")
}
}
}
より凝ったレイアウト
サンプルは凝っているというほどではないですが、もう少しAnkoの機能を使ったレイアウトを見てみましょう。
目標は次のようなTodoを登録できるようなレイアウトを実現です。
このレイアウトのコードは次のようになります。
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
MainActivityUi().setContentView(this)
}
}
class MainActivityUi: AnkoComponent<MainActivity> {
override fun createView(ui: AnkoContext<MainActivity>) = with(ui) {
verticalLayout {
padding = dip(16)
textView("Todo"){
textSize = 24f
}.lparams{
width = matchParent
topMargin = dip(8)
}
val title = editText {
hint = "タイトル"
}
val description = editText {
hint = "概要"
}
button("登録") {
textColor = Color.WHITE
backgroundColor = ContextCompat.getColor(ctx, R.color.colorPrimary)
onClick {
ctx.toast("${title.text} : ${description.text}")
}
}.lparams{
gravity = Gravity.CENTER_HORIZONTAL
topMargin = dip(16)
}
}
}
}
LayoutParamsは、各Viewのすぐ後ろに続けてlparamsをくっつけることで指定できます。
ctxはActivityの拡張プロパティで、これによりContextインスタンスを扱うことができます。
イベントリスナーもbuttonのonClickのように直接記述できます。
まとめ
KotlinのAnkoというライブラリを使った、簡潔なコードでUIを定義する方法を紹介しました。
少し独特なので慣れが入りそうですが、柔軟な記述ができる気がしていいですね。
蛇足ですが、個人的にこのようなDSLを作ることのできるKotlinの言語としてのポテンシャルの高さも面白いと感じました。
