【Android】Button押下イベントのハンドリング in Kotlin

# ➊ はじめに
Androidで、入力イベントをハンドリングする方法を調べました。

# ➋ どんな感じ？
百聞は一見にしかずということで、こんな感じ～になります。
「`Button`」のみのアプリです😁
<img width='200' src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405376/b3d4d4b4-946c-6af1-d8f0-8cb03c271429.png'>
※結果は、`Logcat`で見てください。

# ➌ お勉強ポイント
以下の代表的なものについて実装してみたいと思います。

- クリック
- ロングクリック
- タッチ　( 押す、離す、移動する)

※詳細はこちら👉「[入力イベントの概要](https://developer.android.com/guide/topics/ui/ui-events?hl=ja)」

# ➍ Button押下イベントのハンドリング
例えば「クリック」の場合、イベントを受け取るために「setOnClickListener()」メソッドをコールしておいて、「onClick()」メソッドにイベント発生時の処理を書くだけです。他も同様に実装できます。

## (1) `クリック`イベント
ユーザーがアイテムをタップしたときに呼び出されます。

``` kotlin:snippet
class MainActivity : AppCompatActivity() , View.OnClickListener {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // OnClickListenerを設定
        val button : Button = findViewById(R.id.button)
        button.setOnClickListener(this)
    }

    // onClick
    override fun onClick(view: View){
        when (view.id) {
            R.id.button -> {
                Log.d("app6/onClick", "button")
                // ここへボタンクリック時の処理を書く
                // ・・・
            }
        }
    }
}
```

## (2) `ロングクリック`イベント
- ユーザーがアイテムを長押ししたときに呼び出されます。

- このメソッドのリターンを「`false`」にすると、onClick処理を続けて実行します。onClick処理を続けて実行しないようにする場合は、リターンを「`true`」にします。

``` kotlin:snippet
class MainActivity : AppCompatActivity() ,View.OnLongClickListener{
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // OnLongClickListenerを設定
        val button : Button = findViewById(R.id.button)
        button.setOnLongClickListener(this)

    }

    // onLongClick
    override fun onLongClick(view: View): Boolean {
        when (view.id) {
            R.id.button -> {
                Log.d("app6/onLongClick", "button")
                // ここへボタンロングクリック時の処理を書く
                // ・・・
            }
        }

        // trueはonClick処理しない。falseでonClick処理を続けて実行。
        return(false)
    }
```

## (3) `タッチ`イベント
- アイテムの境界内で、タッチイベントとして判断されるアクション（押す、離す、移動するなどの操作）をユーザーが行ったときに呼び出されます。

- このメソッドのリターンを「`false`」にすると、onTouchイベントの補足を続けます。onTouchイベントの補足を続けて実行しないようにする場合は、リターンを「`true`」にします。

``` kotlin:snippet
class MainActivity : AppCompatActivity() ,View.OnTouchListener {
    @SuppressLint("ClickableViewAccessibility")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // onTouchListenerを設定
        val button : Button = findViewById(R.id.button)
        button.setOnTouchListener(this)
    }

    // onTouch
    @SuppressLint("ClickableViewAccessibility")
    override fun onTouch(view: View, motEvent: MotionEvent): Boolean {
        when (view.id) {
            R.id.button -> {
                when (motEvent.action) {
                    MotionEvent.ACTION_DOWN -> {
                        Log.d("app6/onTouch", "button(ACTION_DOWN)")
                        // ここへボタンタッチ(押す)時の処理を書く
                        // ・・・
                    }
                    MotionEvent.ACTION_UP -> {
                        Log.d("app6/onTouch", "button(ACTION_UP)")
                        // ここへボタンタッチ(離す)時の処理を書く
                        // ・・・
                    }
                    else -> {
                        Log.d("app6/onTouch", "button(" + motEvent.action.toString() + ")")
                        // ここへボタンタッチ(移動など)時の処理を書く
                        // ・・・
                    }
                }
            }
        }

        // trueでコールバック処理終了。falseはコールバック処理を継続。
        return (false)
    }
}
```
# ➎ 実装
仕組みが分かったところで、上記をまとめ、諸々実装していきます。
言語は、「**Kotlin**」で実装します。

## (1) activity_main.xml
> app/src/main/res/layout/activity_main.xml

``` xml:activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
```

## (2) MainActivity.kt
> app/src/main/java/com/poodlemaster/app6/MainActivity.kt

``` kotlin:MainActivity.kt
package com.poodlemaster.app6

import android.annotation.SuppressLint
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.MotionEvent
import android.view.View
import android.widget.Button

class MainActivity : AppCompatActivity() ,View.OnClickListener ,View.OnLongClickListener, View.OnTouchListener {

    //-------------------------------------------------------------------------
    @SuppressLint("ClickableViewAccessibility")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // OnClickListenerを設定
        val button : Button = findViewById(R.id.button)
        button.setOnClickListener(this)
        button.setOnLongClickListener(this)
        button.setOnTouchListener(this)
    }

    //-------------------------------------------------------------------------
    override fun onClick(view: View){
        when (view.id) {
            R.id.button -> {
                Log.d("app6/onClick", "button")
            }
        }
    }

    //-------------------------------------------------------------------------
    override fun onLongClick(view: View): Boolean {
        when (view.id) {
            R.id.button -> {
                Log.d("app6/onLongClick", "button")
            }
        }

        // trueはonClick処理しない。falseでonClick処理を続けて実行。
        return(false)
    }

    //-------------------------------------------------------------------------
    @SuppressLint("ClickableViewAccessibility")
    override fun onTouch(view: View, motEvent: MotionEvent): Boolean {
        when (view.id) {
            R.id.button -> {
                when (motEvent.action) {
                    MotionEvent.ACTION_DOWN -> {
                        Log.d("app6/onTouch", "button(ACTION_DOWN)")
                    }
                    MotionEvent.ACTION_UP -> {
                        Log.d("app6/onTouch", "button(ACTION_UP)")
                    }
                    else -> {
                        Log.d("app6/onTouch", "button(" + motEvent.action.toString() + ")")
                    }
                }
            }
        }

        // trueでコールバック処理終了。falseはコールバック処理を継続。
        return (false)
    }
}
```

# ➏ 結果
クリックやロングクリック、タッチ（押す、離す）の結果は、`Logcat`で見てください。
以下は、2回クリック後に、1回ロングクリックをしたときのログです。

※[`View`] -> [`Tool Windows`] -> [`Logcat`]で起動できます。
※ログ種別を「`Debug`」、検索対象を「`app6/`」に絞ると見やすくなります。

```sh:Logcat
# ボタンクリック
2021-09-09 23:18:25.316 1631-1631/com.poodlemaster.app6 D/app6/onTouch: button(ACTION_DOWN)
2021-09-09 23:18:25.423 1631-1631/com.poodlemaster.app6 D/app6/onTouch: button(ACTION_UP)
2021-09-09 23:18:25.433 1631-1631/com.poodlemaster.app6 D/app6/onClick: button

# ボタンクリック
2021-09-09 23:18:28.348 1631-1631/com.poodlemaster.app6 D/app6/onTouch: button(ACTION_DOWN)
2021-09-09 23:18:28.434 1631-1631/com.poodlemaster.app6 D/app6/onTouch: button(ACTION_UP)
2021-09-09 23:18:28.437 1631-1631/com.poodlemaster.app6 D/app6/onClick: button

# ボタンロングクリック
2021-09-09 23:18:29.405 1631-1631/com.poodlemaster.app6 D/app6/onTouch: button(ACTION_DOWN)
2021-09-09 23:18:29.810 1631-1631/com.poodlemaster.app6 D/app6/onLongClick: button
2021-09-09 23:18:32.699 1631-1631/com.poodlemaster.app6 D/app6/onTouch: button(ACTION_UP)
2021-09-09 23:18:32.699 1631-1631/com.poodlemaster.app6 D/app6/onClick: button
```

# ➐ 以上
「**Android Studio**」でkotlin言語を使って簡単なアプリを作れたら楽しいだろうなと思って少し使い始めました。まずは、機能の基礎勉強をしているので、備忘録も兼ねてここに記録を残しておきます。何番煎じなのかすら分かりませんが、どこかの誰かが役に立ったと言ってくれたら嬉しいです。

お疲れ様でした😊