プログラマに優しい現実指向JVM言語 Kotlin入門

第6回 KotlinでAndroidプログラミング

この記事を読むのに必要な時間:およそ 7 分

ライブラリ・ツール

KotlinでのAndroid開発をより快適にしてくれるライブラリやツールを紹介します。

Kotter Knife

Kotter KnifeはView Injectionライブラリです。頻繁に登場するfindViewByIdによるビューのマッピング作業から解放してくれるライブラリです。Java用のButter KnifeのKotlin版と言えます。ちなみに開発者はAndroid界隈で名高い(どころかスーパースターの)Jake Whartonさんです。

導入は簡単です。リスト7のようにbuild.gradleを編集してください。

リスト7 Kotter Knife導入

dependencies {
  // (略)
    compile 'com.jakewharton:kotterknife:0.1.0-SNAPSHOT'
}
repositories {
  // (略)
  maven {
    url 'https://oss.sonatype.org/content/repositories/snapshots/'
  }
}

導入後,すぐに使い始められます。リスト8にKotter Knifeの簡単な使用例を示します。MainActivityのプロパティとして各ビュー(nameEditTextsubmitButton)を保持しています。onCreateメソッド内でfindByViewIdメソッドを呼び出してビューのマッピングを行うのが通常の方法ですが,このコードにはfindByViewIdが登場しません。setContent View(R.layout.activity_main)を呼び出した後すぐにsubmitButtonに対してクリックリスナを登録しています。

リスト8 Kotter Knife使用例

class MainActivity : Activity() {

  val nameEditText: EditText by bindView(R.id.name_edit_text)

  val submitButton: Button by bindView(R.id.submit_button)

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    submitButton.setOnClickListener {
      val name = nameEditText.getText().toString()
      Toast.makeText(this, name, Toast.LENGTH_SHORT).show()
    }
  }
}

これを可能にしているのは各ビューのプロパティの宣言時にby bindView(ID)と記述したおかげです。bindViewメソッドはKotter Knifeが提供するAPIです。プロパティ宣言のあとにbyと記述しているのはKotlinのDelegated Propertyという機能を使うためです。詳細は割愛しますが,Delegated Propertyとはプロパティへアクセスがあったときに,その処理を別のオブジェクトに委譲するしくみです。Kotter KnifeではこのDelegated Propertyを使って,プロパティとして保持しているビューに初めてアクセスがあったときに,ビューを取得するコードが発動するように作られています。

Anko

次に紹介するのはJetBrainsにより開発されているライブラリ,Anko注1)⁠ です。Android開発を簡単にする便利なAPIが数多くそろっていますが,目玉機能はUIレイアウトを構築するDSL(Domain Specific Language:ドメイン特化言語)です!

Android開発では通常,XMLでレイアウトを組んでJavaコードからそれを利用するという流れが一般的なのはみなさんご存じのとおりです。AnkoはレイアウトをXMLファイルとしてではなく,Kotlinコード上で組み上げるアプローチを提案しています。Kotlinで作成されたDSLを使うので,Kotlinの恩恵をそのまま受けられます。つまり簡潔,型安全,NULL安全ということです。

まずは非常に簡単な例をご覧入れましょう。リスト9では,押すとトーストが表示されるボタンが1つ表示されるようなアクティビティを作っています。

リスト9 Ankoはこんな感じでUIを表現する

class MainActivity : Activity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    verticalLayout {
      button("Click me!") {
        onClick {
          toast("Hello")
        }
      }
    }
  }
}

Kotlinコードですので,Kotlinでできることは何でもできます。たとえばレイアウトの使い回しはどうするのか,という問題はリスト10のように関数に出すのも1つの方法です。

リスト10 UI構築部分を関数として切り出す

class MainActivity : Activity() {
  override fun onCreate(savedInstanceState:
Bundle?) {
    super.onCreate(savedInstanceState)
    val button = createLayout()
    button.setOnClickListener {
      toast("Hello")
    }
  }
}

fun Activity.createLayout(): Button {
  var button: Button? = null
  verticalLayout {
    // ボタンのテキストとしてリソースIDも指定できる
    button = button(R.string.click_me) {
      // ボタンのテキストサイズを指定
      textSize = 24f
    }.layoutParams {
      // マージンを指定
      margin = dip(20)
    }
  }
  // ボタンを返す
  return button ?: throw AssertionError()
}

拡張関数createLayoutで,Ankoを使ってレイアウトを構築しています。そしてAnkoを使って生成したボタンを返して,関数の呼び出し元でボタンにクリックリスナを登録しています。Ankoはまだ発展途上のライブラリで,筆者自身もベストプラクティスを模索中です。

肝心の導入方法ですが,簡単です。リスト11の1行をgradle.buildのdependenciesに追記するだけです。とても面白いライブラリですのでぜひ使ってみてください。

リスト11 Anko導入

compile 'org.jetbrains.anko:anko:0.6.2-15'
注1)
小豆を煮詰めて作る,あの⁠あんこ⁠が名前の由来らしいです。

Kotlin Extensions for Android

最後に紹介するのはKotlin Extensions for Androidというツールです。モチベーションとしてはKotter Knifeと同じくfindViewByIdの排除です。しかしKotlin Extendions for Androidはさらに一歩進めて,プログラマがビューのマッピングを行ったり指定したりするような記述すら必要ありません。

簡単な具体例を示します。リスト12activity_main.xmlという名前のレイアウトファイルです。そして,このレイアウトファイルを使うMainActivityの定義がリスト13です。

リスト12 activity_main.xml

<RelativeLayout xmlns:android="http://schemas.
android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent">

  <Button
    android:id="@+id/helloButton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Hello"/>
</RelativeLayout>

リスト13 ビューオブジェクトが自動生成されている

package com.taroid.sample

import android.app.Activity
import android.os.Bundle
import android.widget.Toast
import kotlinx.android.synthetic.activity_main.helloButton

public class MainActivity : Activity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    helloButton.setOnClickListener {
      Toast.makeText(this, "Hello", Toast.LENGTH_SHORT).show()
    }
  }
}

リスト13では,onCreate内でいきなり登場するhelloButtonに対してクリックリスナを登録しています。Kotter Knifeのときと異なり,helloButtonはプロパティに宣言されていなければDelegated Propertyも使用されていません。このhelloButtonどこからやってきたのかと言うとKotlin Extensions for Androidによって生成され,それをインポートすることでMainActivity内で使えるようにしています。自動生成されるビューの完全な名前を一般化するとkotlinx.android.synthetic.<レイアウトファイル名>.< リソースID>のような形式になります。

Kotlin Extensions for Androidを導入するには,まずプラグインをインストールします。同名のプラグインをAndroid Studioにインストールし,再起動します。そしてbuild.gradleをリスト14のように編集して,使えるようになります。

リスト14 Kotlin Extensions for Android導入

buildscript {
  // (略)

  dependencies {
    // (略)
    classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version"
  }
}

まとめ

Android Studioにプラグインを入れるだけで,すぐにKotlinによるAndroidプログラミングを体験できます。KotlinコードからシームレスにAndroidのAPIを呼び出せます。Kotlinの独特な文法,たとえば拡張関数やNULL安全などもAndroid上で動きます。

ボタンのクリックリスナのような,抽象メソッドが1つしかないインターフェースとして関数リテラルを使うことができます。クリックリスナの登録のときに,匿名クラスを書いて,メソッドをオーバーライドするようなノイズの多い記述をKotlinではしなくて済みます。

Contextを引数に取るような便利メソッドの定義の際には,拡張関数が非常に威力を発揮するでしょう。Contextに対する拡張関数とすれば,呼び出し側のコードが目に優しく直感的なスタイルになります。

便利なライブラリ・ツールを3つ紹介しました。Kotter KnifeはButter KnifeのKotlin版で,Delegated PropertyというKotlinの機能をうまく利用して実現されているView Injectionライブラリです。AnkoはAndroid開発におけるDSLセットで,とくにUIレイアウトが興味深いです。Kotlinの簡潔で安全な特長をUIレイアウトに活かせるのはうれしいです。Kotlin Extensions for AndroidはView Injectionのためのツールで,ビューのマッピングが全自動なため作業が減り,コードもすっきりします。

おわりに

全6回に及ぶKotlin入門連載,いかがでしたか? 業務でKotlinを使う日は遠からず来るのではないかと期待しています。現時点でKotlinはβ版という位置づけですが,そろそろバージョン1.0がリリースされそうな気配を感じています。今後も筆者のブログでKotlin情報の発信は続けていくので,新しいマイルストーンがリリースされたときなどにはチェックしてください。

Kotlinでみなさまのプログラミングが少しでも快適に,そして今よりもっと楽しくなればエバンジェリスト注2冥利に尽きます。Let's enjoy Kotlin!

注2)
自称ですが。
Software Design

本誌最新号をチェック!
Software Design 2017年11月号

2017年10月18日発売
B5判/176ページ
定価(本体1,220円+税)

  • 第1特集
    データ分析に効く
    SQL50本ノック
  • 第2特集
    なぜ,コンピュータは割り算が下手なのか!?
  • 一般記事
    Redash+SQL勉強会で業務改善!
    エンジニア任せにしないデータ分析の基盤作り
  • 一般記事
    ホワイトボックススイッチって何?
    ユーザがソフトウェアを自作する新しいスイッチの形

著者プロフィール

長澤太郎(ながさわたろう)

早稲田大学情報理工学科を2012年に卒業。同年入社したメーカー系SIerを経て,2013年にエムスリー株式会社へ入社。以来,世界の医療を変革するためソフトウェアエンジニアとして従事。

日本Kotlinユーザグループ代表,日本Javaユーザグループ幹事を務める。国内初となるKotlin入門書「Kotlinスタートブック」(リックテレコム)の著者。

ビールとディズニーが大好き。

コメント

コメントの記入