DEV Community

kaede
kaede

Posted on

Android 基礎 -- Part 04 TextField に入れた値を Button 押下でコンソールに出力する

why

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

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


何をするのか

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

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


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

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

@Composable
fun EditScreen() {
    var body by remember { mutableStateOf("") }
    OutlinedTextField(
        value = body, onValueChange = { body = it},
    )
    Button(onClick = {
        println(body)
    }) {
    }
}
Enter fullscreen mode Exit fullscreen mode

Image description

Image description

これでボタンをクリックすると、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

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


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

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

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

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

@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()
         )
    }
Enter fullscreen mode Exit fullscreen mode

Image description

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


ボタンをつける

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

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

Enter fullscreen mode Exit fullscreen mode

これではいった

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


Button にアイコンを入れる

Textだから悪い説がある

Icon にしてみる

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

公式を参考に作る

Icon(
   Icons.Rounded.ShoppingCart,
   contentDescription = stringResource(id = R.string.app_name) 
)
Enter fullscreen mode Exit fullscreen mode

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

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

Top comments (0)