僕とコードとブルーハワイ

omega (@equal_001) の日記

Android開発でKotlinを学ぶログ1 開発環境の準備とAndroid projectとView, Layout, Click Event

今日から同僚にAndroid開発の基本を伝授してもらえることになったので忘却録を書いていく.
Kotlinの勉強も合わせて行うので, 以後使用言語はKotlinがメインとなる.

開発環境の準備

近年では Android Studio が主流とのことなのでこれをInstallした. Downloadにちょっと時間がかかるくらいで特に躓いた点は無し.

Android Project 概要

MainActivity.kt

  • onCreate()
    • こいつがエントリポイント, 一番最初に呼び出される
    • MainAtivityは画面描画する前に呼び出される
  • setContentView(R.layout.activity_main)
    • ここでres配下のxmlファイルが呼び出される
    • 内部でres配下にあるxmlファイル群に一つずつidをふっていて, setContentView() にID群(R.layout.activity_main)が渡された結果, 初動のUI表示の実行がされる.
    • つまりこれをコメントアウトすると真っ白な画面が表示される.
    • 内部的に一意な数値として扱えるメリットがある

res/layout

  • UIの定義が書かれたxml fileを配置する場所
  • ここにButtonとかTextとかの定義をガンガン書いていく

String Resource (res/values/strings.xml)

  • layout や Activity から呼び出し可能なresourcesを管理するfile
  • 例えば 0 と書いておくと initial_text というIDでTextViewに初期代入してやると起動時に0が表示される
  • 初期表示やローカライズ(多言語対応)するときなどに使うと便利

UI定義でよく使われるものたち

基本的に各ViewにIDを付けてActiviryで呼び出すという形っぽい.

よく使われるLayout

1 Layoutにつき1 XMLというイメージでやることが多いらしい.
ただし, 入れ子にもできるし他のxmlに外出ししてincludeしたりできる.
本格的にfileを分けたりなんだりするとCustomView?という概念がでてくるらしいけど長い話になるのでまた今度と言われた.

  • Linear Layout
    • vertical: 上から下, holizone: 右から左 の繰り返しでコンテンツ表示するlayout
    • layout_widthでよく使われる単位はdp(端末毎に違うpixcelを解消するために生まれた単位. これを使うとどの端末でも大体同じ大きさになる) , fontはsp(スマホ端末で文字大きさ変えても反映される)
  • Relative layout
    • 親に対する子の要素を決めて配置できる. cssのrelativeみたいなやつ
  • Frame layout
    • point 0.0からframeを重ねていくイメージの配置方法
    • 上のメニューバーを固定しつつメインコンテンツをスクロールするみたいなものを作りたいときに便利だったり

よく使われるView

  • Text View
    • 編集できない, ただ表示するだけのView
    • Pythonistaでいうlabelにあたる
  • EditText View
    • 編集可能な方のText View
  • Image View
    • その名の通り画像を表示するView
  • Button
    • その名の通り, ボタンのネイティブUIを呼び出したいときに使うやつ
    • これも実はVIewの仲間らしい

Click Event

  • Buttonだけかと思われがちだが, Viewならどこでもclick eventが取れる
  • 方法は簡単で, Viewにidを付けてActivity側でsetOnClickListener()するとeventが取れる

Activity_main.xml

<Button
        android:id="@+id/count"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/count_label" />

MainActivity.kt

val count_button: Button = this.findViewById(R.id.count)
count_button.setOnClickListener { view: View? ->
    Log.d("MainActivity", "this is log")  // count buttonが押される度にconsole logに"this is log"と表示される
}

Kotlin学びポイント

Buttonを押すと+=するCounterの実装をしたのだけれど, 私は愚直に実装してしまった.

val count_button: Button = this.findViewById(R.id.count)
val text: TextView = this.findViewById(R.id.result)
var count = 0
count_button.setOnClickListener { view: View? ->
    count += 1
    text.text = count.toString()
}

同僚はおしゃれなコードを書いていた.

val text = this.findViewById<TextView>(R.id.count_text)
var count: Int by Delegates.observable(0) { _, _, new ->
    text.text = new.toString()
}
this.findViewById<Button>(R.id.count_up_button).setOnClickListener {
    count = count + 1 
}

Observable property をうまく使った例.

Delegates.observable() は、2つの引数を取ります。初期値と修正のためのハンドラです。ハンドラは(割り当てが行われた 後 に)プロパティに割り当てるたびに呼び出されます。それには3つのパラメータがあり、割り当てられているプロパティ、古い値、そして新しい値です

_, _, new は prop, old, new の順番で値が入れられていて, 今回は count+= された結果, つまり最新のcount数が入ったnewだけ必要なので, propとoldはアンダースコアで捨てている.

そういえば by Delegatesを使うと+=記法をしたときにerrorになるらしく, 仕方なく count = count + 1 と書いているらしい.

今日はここまで.