はいどうも、こんばんは。
Ankoの紹介をします。
Anko イズ 何
AnkoはAndroidのレイアウト構築をするためのものです。
DSL...何か決まっている問題を解決するための言語です。AnkoはAndroidのレイアウト構築だけを考えられて作られた言語です。つまり...なんで使わないの。
ちなみにこちらJetbrains製です。中身もkotlinで書かれています。
なので、もちろんKotlinの強みであるNull安全や型推論等サポートされているわけです。
導入
gradleプロジェクトなら一瞬です。
依存関係を記述します。
compile 'org.jetbrains.anko:anko-sdk15:0.8.3'
たった一行で済みます。うんうん。
ただ、新しい環境(記述時2.3)だと動きません。
僕はAndroidStudio2.0で動かしました。
凄く粗削りですがこちらにコードもおいてあります。かなり記事にする上で端折っているのでよかったら合わせて読んでください。
使おう
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:text="登録"/>
</LinearLayout>
よく見る(見ない)レイアウト構成です。
LinearLayoutの中にEditTextとButtonが入っています。
まずはこれをAnkoってみましょう。
linearLayout {
orientation = LinearLayout.VERTICAL
editText().lparams(width = matchParent, height = wrapContent)
button(R.string.subscribe) {
gravity = Gravity.RIGHT
}.lparams(width = wrapContent, height = wrapContent)
}
超簡単じゃないですか。というか見たことがあると思います。ほぼxmlのままです。
xmlが書ければankoが書ける...ankoが書ければxmlが書ける...といったことが読んでもらえばわかると思います。
プロジェクトへの進言もしやすいですね。
とはいえこれだけではまぁ...使う気にはならないですよね。
もーっといろいろスマートになります。
id要らない
idが不要になります。どういうことでしょうか。
まずはActivityのほうにクリック後の処理を書きましょう。
fun subscribe(ui: AnkoContext<MainActivity>, text: String) {
ui.doAsync {
Thread.sleep(500)
activityUiThreadWithContext {
if (checkCredentials(text)) toast("Login")
}
}
}
登録ボタンをしてる感処理です。
override fun createView(ui: AnkoContext<MainActivity>) = with(ui) {
linearLayout {
orientation = LinearLayout.VERTICAL
val name = editText().lparams(width = matchParent, height = wrapContent)
button(R.string.subscribe) {
onClick {
ui.owner.subscribe(ui,name.text.toString())
}
gravity = Gravity.RIGHT
}.lparams(width = wrapContent, height = wrapContent)
}
}
そして先ほど用意したレイアウトのほうに戻ります。
少しいじってありますが。まずはbuttonにOnClick
が定義してあるのがわかると思います。
そしてその中でMainActivityにあるsubscribe
メソッドを呼び出しているのがわかると思います。
これは普段だったら....
findViewById(R.id.button).setOnClickListener {
subscribe()
}
といったことをしなきゃいけないものだと思います。Ankoなら昔からずっと言われている冗長番長findViewById
を消し去り、.xmlからもid属性を消すことができます。(というか.xmlが消えるんだけど)
さらに、
今までだったら...
findViewById(R.id.button).setOnClickListener {
subscribe((findViewById(R.id.edittext) as EditText).text.toString())
}
と書いていたものが。
もう一点先ほどのコードと変わったところがあります。
val name = editText().lparams(width = matchParent, height = wrapContent)
EditText
を変数に代入しています。これもまたidを消すことができていて、subscribe
メソッドでString
を渡さなければいけないところを楽にしてくれています。
OnClick
の中で
ui.owner.subscribe(ui,name.text.toString())
nameをごにょるだけでなんとかなっています。素晴らしい...
CustomViewを作る
ただこれだと少しネストが深いとうんざりしちゃいますかね?(もちろんそれは.xmlにも言えることですが)どうすれば解決するでしょう。とりあえずCustomView
にしてみましょう。
まぁとりあえずいつもの.xmlで。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<ImageView
android:id="@+id/imageview"
android:layout_width="80dp"
android:layout_height="80dp"
tools:src="@android:drawable/alert_dark_frame"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/text_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="6dp"
tools:text="佐々木"/>
<TextView
android:id="@+id/text_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@android:color/darker_gray"
tools:text="\@Sasaki_YuKi"/>
<ImageView
android:id="@+id/image_lock"
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_gravity="center"
android:src="@android:drawable/ic_lock_lock"
android:visibility="gone"
tools:visibility="visible"/>
</LinearLayout>
<TextView
android:id="@+id/text_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="4dp"
tools:text="今日も頑張って仕事をしよう。週末はおいしいものでも食べたいなぁ。"/>
</LinearLayout>
</LinearLayout>
こんなやつです。
Ankoで書くとこんな感じです。
private fun init() = AnkoContext.createDelegate(this).apply {
orientation = LinearLayout.HORIZONTAL
image = imageView(imageResource = android.R.drawable.ic_menu_report_image) {
layoutParams = LinearLayout.LayoutParams(dip(80), dip(80))
}
linearLayout {
layoutParams = LinearLayout.LayoutParams(matchParent, wrapContent)
orientation = LinearLayout.VERTICAL
padding = dip(10)
linearLayout {
orientation = LinearLayout.HORIZONTAL
textView(text = "佐々木") {
}.lparams(width = wrapContent, height = wrapContent) {
rightMargin = dip(6)
}
textView(text = "@Sasaki_Yuki") {
textColor = android.R.color.darker_gray
}.lparams(width = wrapContent, height = wrapContent)
imageView {
setImageResource(android.R.drawable.ic_lock_lock)
visibility = View.VISIBLE
}.lparams(width = dip(15), height = dip(15)) {
gravity = Gravity.CENTER
}
}.lparams(width = matchParent, height = wrapContent)
textView(text = "今日も頑張って仕事をしよう。週末はおいしいものでも食べたいなぁ。") {
padding = dip(4)
}.lparams(width = matchParent, height = wrapContent)
}
}
(toolsに当たるものを見つけることができなかった)
Root要素がLinearLayout
のためImageView
と名前とかが入っているLinearLayout
が入っています。
@Suppress("NOTHING_TO_INLINE")
inline fun ViewManager.myLikeTweetView(theme: Int = 0) = myLikeTweetView({}, theme)
inline fun ViewManager.myLikeTweetView(init: LikeTweetView.() -> Unit, theme: Int = 0) = ankoView(::LikeTweetView, theme, init)
呼び出し口を用意して、Activity側から呼び出します。
val name = editText().lparams(width = matchParent, height = wrapContent)
button(R.string.subscribe) {
onClick {
ui.owner.subscribe(ui,name.text.toString())
}
gravity = Gravity.RIGHT
}.lparams(width = wrapContent, height = wrapContent)
myLikeTweetView()
これでよい。
これの呼び出し口にRecyclerViewならConvertViewやらEntityを渡せば反映させることもできるようになるわけです。
終わりに
以上です。
Kotlinを使っているなら思い切ってankoにしてみるのもいいんじゃないでしょうか。
いつかより応用的な記事を書ければいいなと思います。
凄く粗削りですがこちらにコードもおいてあります。かなり記事にする上で端折っているのでよかったら合わせて読んでください。