Mokelab Blog

ボタンタップ時の処理を記述する

今回は、「ボタンをタップしたときにこの処理を実行する」といった、イベントの設定方法について説明します。

onCreateView()

Android アプリの画面は Fragment の onCreateView()で、レイアウト XML から生成しています。

class TitleFragment : Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_title, container, false)
    }
}

inflater.inflate()で指定したレイアウト XML ファイルを元に、View を組み立てます。第 1 引数はレイアウト XML のファイル名ではなく、R.layout.ファイル名という形式になっている点に注意しましょう。

ボタンを配置する

イベント設定の練習用として、画面の左上にボタンを配置してみましょう。こちらの手順で最初の画面を追加した場合、TitleFragment という名前のフラグメントを追加しています。TitleFragment 内のonCreateView()ではfragment_titleを元に View を生成しているので、編集すべきレイアウト XML ファイルはres/layout/fragment_title.xmlとなります。なお、R.layout.fragment_title のfragment_titleの部分にカーソルを移動させ、右クリック →Go to→Declaration で該当のファイルにジャンプすることができます。

ボタンを配置したら、ボタンの ID をlogin_buttonに変更しておきます。このIDは後ほど使用します。

ボタンを取り出す

ボタンをタップしたときの処理を記述するには、対象となるボタンを Kotlin 側で取り出す必要があります。まず、inflater.inflate()の結果を次のように変数にいれておきます。

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    // Inflate the layout for this fragment
    val root = inflater.inflate(R.layout.fragment_title, container, false)
    return root
}

rootにはレイアウト XML のルート要素となるオブジェクト(ここでは ConstraintLayout)が入っています。ここから対象となるボタンを取り出すには、findViewById()を使います。引数には先ほどボタンに設定した ID を、R.id.設定したIDの形式で指定します。

val root = inflater.inflate(R.layout.fragment_title, container, false)
val button = root.findViewById<Button>(R.id.login_button)
return root

これで View ツリーからボタンが取り出せました。

リスナーを設定する

今回のゴールであるイベントを設定するには、取り出したボタンに対してリスナーを設定します。例えばタップされたときのリスナーを設定するにはsetOnClickListener()を使います。

val root = inflater.inflate(R.layout.fragment_title, container, false)
val button = root.findViewById<Button>(R.id.login_button)
button.setOnClickListener(object : View.OnClickListener {
    override fun onClick(v: View?) {
        Toast.makeText(activity, "ボタンがタップされたよ", Toast.LENGTH_SHORT).show()
    }
})
return root

ボタンがタップされると、渡したリスナーのonClick()が呼ばれます。タップされたことが判別できるよう、Toastを使って画面にメッセージを表示した例です。

コラム:SAM 変換

View.OnClickListener は Java でインターフェースとして定義されています。そのため、ここではobject : View.OnClickListener とすることで無名オブジェクトとして実装してみました。しかしこのコードをそのまま Android Studio で貼り付けると、この部分に黄色の下線が表示されます。

Kotlin では、

場合に限り、無名オブジェクトを次のように作ることができます。このようなインターフェースを SAM(Single Abstract Method)インタフェースと呼びます。

val l = View.OnClickListener { v ->
    Toast.makeText(activity, "ボタンがタップされたよ", Toast.LENGTH_SHORT).show()
}

onClick() の中身をラムダ式で記述し、コンパイル時にいい感じに変換してくれます。この変換を SAM 変換と呼びます。なぜか Java で定義されているインターフェースでしか使えないので注意しましょう。

SAM 変換を活用すると、次のようにシンプルに記述することができます。

button.setOnClickListener(View.OnClickListener {
    Toast.makeText(activity, "ボタンがタップされたよ", Toast.LENGTH_SHORT).show()
})

しかし Android Studio は View.OnClickListener の部分に対して下線で警告を表示します。引数の型からここに記述できるのはView.OnClickListener であるのが自明なので、さらに次のように記述することができます。

button.setOnClickListener({
    Toast.makeText(activity, "ボタンがタップされたよ", Toast.LENGTH_SHORT).show()
})

Android Studio はさらに警告を出します。Kotlin では、関数/メソッドの最後の引数がラムダ式になる場合、()が省略できます。

button.setOnClickListener {
    Toast.makeText(activity, "ボタンがタップされたよ", Toast.LENGTH_SHORT).show()
}

とてもシンプルになりました。

まとめ

View ツリーから ID 指定で View を取り出す方法と、イベントの設定方法を説明しました。タップ時の処理以外にもいろんなイベントが用意されているので、ドキュメントを読みながらリスナーを設定してみましょう。

本サイトではサービス向上のため、Google Analyticsを導入しています。分析にはCookieを利用しています。