Android 基礎 -- Part 04 TextField に入れた値を Button 押下でコンソールに出力する
Tags: android, jetpackcompose
Published: 2023-01-09 10:32:41


## why

前回の記事で、TextField を包んだコンポーザブルにステートを定義した。
これにより、TextField にキーボードから値を入れることができるようになった。

入力欄に値を入れられたので、次はこの値を出力したい。

---

## 何をするのか

UI から入力した値の出力、
HTML だったら window.alert や　console.log をするところだ。
Android の Kotlin では println で出力すると、起動しているアプリでログが見れるようなので、println で出力してみる。

プリントするトリガーのために、ボタンにステートと println を結びつける。

---

## TextFiled と同じコンポーザブルに Button をおいて、onClick でステートをプリントする

単純に TextFiled を包んでいるコンポーザブルに、Button も入れる。
これでコンポーザブルの中にあるステートなので、Button でそのステートを　プリントできる。

```kotlin
@Composable
fun EditScreen() {
    var body by remember { mutableStateOf("") }
    OutlinedTextField(
        value = body, onValueChange = { body = it},
    )
    Button(onClick = {
        println(body)
    }) {
    }
}
```


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6crd9wnp91nz7l7mo6k6.png)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2tz3qncx4p4xhwsadccd.png)

これでボタンをクリックすると、TextFiled の value と同期されているステートの値が Android のコンソールに出力された。

---

## 重なりを解決するために Scafold と Column / Row を調べる

これでは TextField と Button を同じ Composable に入れているので、
見た目が重なってしまっている。

しかし、別の Composable にしてしまうと、共通のステート変数を使えない。

Scafold にまとめるとこれを解決できるようだ

k8s の skafold とはスペルが違う。

https://developer.android.com/jetpack/compose/layout?hl=ja#composable-functions

この記事に、重なる実例がわかりやすく出ている。

https://developer.android.com/jetpack/compose/layout?hl=ja

Column と Row でも治せるらしい。

---

## とりあえず Scaffold で TextField と　Button を包む

https://developer.android.com/jetpack/compose/layout?hl=ja#slot-based-layouts

https://www.youtube.com/watch?v=1ReyAfiQCto&list=PLgAI_5b_7BdRaBPAD5RMrzjoSwefDXpkw&index=5

Scaffold と Appbar を使うことで、指定の場所にスロットとして
Composable を嵌めることができる。

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dxzyqu4rduhj1oqyxlpr.png)

Scaffold の中に TextFiled と Button　を入れるだけではダメだった。

---

## Scaffold で TopAppBar の中でボタンを呼び、下に TextField を入れる

https://www.youtube.com/watch?v=o74QgfQ-fIM&list=PLgAI_5b_7BdRaBPAD5RMrzjoSwefDXpkw&index=11

Scaffod で TopAppbar を出せば、綺麗に下に TextField が並べられるらしい。

まずは外殻だけ作ってみる

```kotlin
@Composable
fun EditScreen() {
    var body by remember { mutableStateOf("") }
    Scaffold(
        topBar = {
            TopAppBar(
                title = {
                    Text(text = "NoteApp")
                }
            )
        }
    ) { paddingValues ->
         TextField(
             value = body,
             onValueChange = { body = it},
            modifier = Modifier.padding(paddingValues).fillMaxWidth()
         )
    }
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ylztk5qviaxqmsj2bh3l.png)

これで 
Scaffold の中に AppBar
Scaffold の下に TextField
これらを一つの Composable の中に並べることができた。

---

## ボタンをつける

次に AppBar にボタンを入れてやる

```kotlin
    Scaffold(
        topBar = {
            TopAppBar(
                title = {
                    Text(text = "NoteApp")
                },
                actions = {
                    IconButton(onClick = {
                        println(body)
                    }) {
                        Text(text = "print")
                    }
                }
            )
        }
    
```

これではいった

しかし、叩いてもログがでない

---

## Button にアイコンを入れる

Textだから悪い説がある

Icon にしてみる

https://developer.android.com/jetpack/compose/graphics/images/material

公式を参考に作る

```kotlin
Icon(
   Icons.Rounded.ShoppingCart,
   contentDescription = stringResource(id = R.string.app_name) 
)
```

R はなにか不明だが import
Shopping カートのコンテント？文字列？がないので app_name にした

これで、トップバーとボタン、そしてテキストフィールドを綺麗に並べて、テキストフィールドの中身のステートをボタンで扱うことができた。