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の言語としてのポテンシャルの高さも面白いと感じました。