【Kotlin研修2日目】トーストとListViewへのリスナ定義

# トースト
[参考: トースト](https://developer.android.com/guide/topics/ui/notifiers/toasts?hl=ja)

## Toastオブジェクトのインスタンス化

### 定義

```kotlin
Toast.makeText(context: Context, text: CharSequence, duration: Int)
// パラメータ
// context: トーストを表示させるアクティビティオブジェクト(=Activityインスタンス)
// text: トーストで表示する文字列
// duration: トーストを表示する時間
```

### サンプルコード

```kotlin:MainActivity.kt
val show = "test"

val toast = Toast.makeText(this@MainActivity, show, Toast.LENGTH_LONG)
```

#### 説明

##### `Context`クラス
`Activity`クラスの親クラス。

##### `context`
`this`は自身の`インスタンス`を指すが、コンパイルエラーや誤作動を避けるために`this@アクティビティクラス名`という記述を行う。
また、`Context`クラスが保持する`applicationContext`プロパティも利用できるが、`コンテキスト`の指定が不明瞭になるため非推奨。

##### `duration`
トーストを表示する`時間`を、`Toastクラスの定数`を使って指定する。
`Toast`クラスの定数は以下の2種類。

|定数|内容|
|:--|:--|
|`Toast.LENGTH_LONG`|長い|
|`Toast.LENGTH_SHORT`|短い|

## Toastオブジェクトの表示

### サンプルコード

```kotlin
toast.show()
```

# リスト形式のビュー(ListView, Spinner)のリスナクラス

```kotlin:MainActivity.kt
class MainActivity: AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        ...
    }

    // ListViewのItemをタップした場合のリスナクラス(リスナ)
    // AdapterView: ListView, Spinnerの親クラス
    // OnItemClickListener: "タップ"イベントを検知するAdapterViewのメンバインタフェース
    private inner class ListItemClickListener: AdapterView.OnItemClickListener {

        // タップ時の処理(イベントハンドラ)
        // view: (タップされた)ビュー(=ListViewのItem(=TextView))
        // position: (タップされた)ItemのIndex
        // id: (SimpleCursorAdapterを使用する場合)DBの主キー
        //     (それ以外の場合)positionと同じ値
        override fun onItemClick(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {

            // ListViewのItem(TextView)の値をIndex番号から取得, String型に変換
            // parent: AdapterView
            // getItemAtPosition(): 指定したIndexのtext値を取得(返り値はAny型)
            val item = parent?.getItemAtPosition(position) as String
            // トーストで表示する文字列
            val show = "you chose: " + item

            // Toast.makeText(context:text:duration:): Toastオブジェクトのインスタンス化
            // context: トーストを表示させるアクティビティオブジェクト(=Activityインスタンス)
            // text: トーストで表示する文字列
            // duration: トーストを表示する時間
            val toast = Toast.makeText(this@MainActivity, show, Toast.LENGTH_LONG)

            // トーストの表示
            toast.show()
        }
    }
```

# リスナのセット

## セッタがリスナプロパティのセッタでない場合
[参考: 研修1日目](https://qiita.com/b150005/items/20209e1c096e9e7a43bd)
`setOnClickListener()`メソッドは、`onClickListener`プロパティの`セッタ`ではないため、
`onClickListener`プロパティにリスナを直接代入(=`アクセス`)し、リスナとして定義することができない。

```kotlin:MainActivity.kt
// リスナとするオブジェクトの定義
val btClick = findViewById<Button>(R.id.btClick)
// リスナクラスのインスタンス化(実体化)
val listener = HelloListener()

// オブジェクトをリスナとして設定
btClick.setOnClickListener(listener)
```

## セッタがリスナプロパティのセッタである場合
`setOnItemClickListener()`メソッドは、`onItemClickListener`プロパティの`セッタ`であるため、
`onItemClickListener`プロパティにリスナを直接代入することで、自動的に`セッタ`を呼び出し、リスナとして定義することができる。

```kotlin:MainActivity.kt
// リスナとするオブジェクトの定義
val lvMenu = findViewById<ListView>(R.id.lvMenu)

// 本来はこっち
// リスナクラスのインスタンス化(実体化)
val listener = ListItemClickListener()
// オブジェクトをリスナとして設定
lvMenu.setOnItemClickListener(listener)

// 上記の条件を満たす場合(直接リスナプロパティにリスナをセット)
lvMenu.onItemClickListener = ListItemClickListener()
```

## 使い分け
上記条件に該当する場合は、`Android Studio`が`Use property access syntax`とプロパティへのアクセスで記述するように提案してくれるので、最初から意図的に`セッタ`を呼び出してリスナを定義する。