0Pricing
Android Academy · レッスン

TextFieldとユーザー入力

Composeでユーザーのテキスト入力を受け取ります。

「TextFieldとユーザー入力」はCoddyKit上の無料Android Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはAndroid Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Android Academyコースには全4レッスンが含まれています。

ユーザー入力の取得

ほとんどすべての実際のアプリでは、名前、メールアドレス、検索クエリなど、ユーザーに何かを入力してもらう必要があります。Jetpack Composeでテキスト入力を行う基本部品はTextFieldです。

このレッスンでは、テキストフィールドの表示、ユーザーが入力した内容の読み取り、フィールドとアプリの状態の同期について学びます。これは、これから作るあらゆるフォームの基礎になります。

最初のTextField

TextFieldには、表示する現在のテキストを表すvalueと、ユーザーが入力したときの処理を表すonValueChangeコールバックの2つが必要です。

Composeは宣言的なので、フィールド自身がテキストを保持することはありません。皆さんがテキストを状態として保持し、それをフィールドに渡し返します。このパターンをstate hoistingと呼びます。

@Composable
fun NameField() {
    var name by remember { mutableStateOf("") }

    TextField(
        value = name,
        onValueChange = { name = it }
    )
}

値のループの仕組み

最も重要な考え方は、TextFieldがvalueに渡した内容をそのまま表示することです。ユーザーがキーを押すと、Composeは新しいテキストを引数にしてonValueChangeを呼び出します。

  • その新しいテキストを状態に保存します。
  • 状態が変わると再コンポジションが発生します。
  • 更新されたvalueでフィールドが再描画されます。

onValueChange内で状態の更新を忘れると、valueが変わらないため、フィールドが固まったように見えます。

var name by remember { mutableStateOf("") }

TextField(
    value = name,
    onValueChange = { newText -> name = newText }
)

ラベルとプレースホルダーの追加

テキストフィールドだけでは、何を入力すればよいのかユーザーに伝わりません。label(フィールドの上に浮かんで表示されるラベル)とplaceholder(空のときに表示されるヒント)を追加しましょう。

こうした小さな工夫で、フォームははるかに分かりやすくなります。

var email by remember { mutableStateOf("") }

TextField(
    value = email,
    onValueChange = { email = it },
    label = { Text("Email") },
    placeholder = { Text("you@example.com") }
)

OutlinedTextField

Material Designには主に2つのスタイルがあります。TextFieldは塗りつぶされた背景を持ち、OutlinedTextFieldはフィールドの周囲に枠線を描画します。APIは共通なので、切り替えは簡単です。

Outlinedフィールドは、縦方向に並べたときに見やすいため、フォームでよく使われます。

var username by remember { mutableStateOf("") }

OutlinedTextField(
    value = username,
    onValueChange = { username = it },
    label = { Text("Username") },
    singleLine = true
)

先頭アイコンと末尾アイコン

アイコンでフィールドを装飾できます。leadingIconは先頭に表示され(検索やメールのアイコンに適しています)、trailingIconは末尾に表示されます(クリアボタンによく使われます)。

アイコンがあると、フィールドの目的がひと目で分かります。

var query by remember { mutableStateOf("") }

OutlinedTextField(
    value = query,
    onValueChange = { query = it },
    label = { Text("Search") },
    leadingIcon = {
        Icon(Icons.Default.Search, contentDescription = null)
    }
)

クリアボタン

フィールドをクリアする小さな「x」は、よく使われるUXパターンです。テキストがあるときだけ、trailingIconスロットとIconButtonを使って表示します。

クリアする処理は、状態を空文字列に戻すだけだという点に注目してください。

var text by remember { mutableStateOf("") }

OutlinedTextField(
    value = text,
    onValueChange = { text = it },
    label = { Text("Note") },
    trailingIcon = {
        if (text.isNotEmpty()) {
            IconButton(onClick = { text = "" }) {
                Icon(Icons.Default.Clear, contentDescription = "Clear")
            }
        }
    }
)

1行と複数行

デフォルトでは、TextFieldは複数行に拡張できます。名前やメールアドレスなどでは、singleLine = trueを設定して、ユーザーが改行を入力できないようにします。

長いメモの場合は複数行のままにし、必要に応じてmaxLinesで高さの上限を設定します。

var bio by remember { mutableStateOf("") }

OutlinedTextField(
    value = bio,
    onValueChange = { bio = it },
    label = { Text("Bio") },
    maxLines = 4
)

入力にリアルタイムで反応する

テキストの状態を自分で管理しているため、その変化にすぐ反応できます。典型的な例は、フィールドの下に入力文字数をリアルタイムで表示することです。

キーを1回押すたびにtextが更新され、フィールドとその下の文字数の両方が再コンポジションされます。

var text by remember { mutableStateOf("") }

Column {
    OutlinedTextField(
        value = text,
        onValueChange = { text = it },
        label = { Text("Tweet") }
    )
    Text("${text.length} / 280")
}

入力値の変換

ユーザーが入力した内容を保存する前に正規化したい場合があります。onValueChange内で、新しい値を先に変換できます。

ここでは、ユーザー名を小文字に変換し、空白を取り除きます。ループを自分で制御しているため、フィールドには常に整形済みの値が表示されます。

var handle by remember { mutableStateOf("") }

OutlinedTextField(
    value = handle,
    onValueChange = { input ->
        handle = input.lowercase().filterNot { it.isWhitespace() }
    },
    label = { Text("Handle") },
    singleLine = true
)

純粋なKotlin:ハンドルの整形

上の変換ロジックは、通常のKotlinだけで記述されています。Androidがなくても単独でテストできます。ここでは、同じ整形ルールを単独で実行します。

このようなロジックを純粋な関数にしておくと、ユニットテストが簡単になります。

fun cleanHandle(input: String): String =
    input.lowercase().filterNot { it.isWhitespace() }

fun main() {
    println(cleanHandle("  John Doe "))
    println(cleanHandle("ADA Lovelace"))
}

理解度チェック

TextFieldのonValueChangeコールバックが、valueに渡した状態を一度も更新しなかった場合、どうなるでしょうか。

まとめ

Composeにおけるテキスト入力の基本を学びました。

  • TextFieldとOutlinedTextFieldは、valueとonValueChangeコールバックを受け取ります。
  • remember { mutableStateOf(...) }でテキストを保持し、変更のたびに更新します(state hoisting)。
  • label、placeholder、先頭/末尾アイコン、singleLineで見た目と動作を調整できます。
  • 状態を自分で管理するため、入力にリアルタイムで反応したり、入力中に値を変換したりできます。

次は、1つのフィールドだけでなく、フォーム全体の状態を管理します。

よくある質問

「TextFieldとユーザー入力」レッスンは無料ですか?

はい。「TextFieldとユーザー入力」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Android Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Android Academyコースには全4レッスンが含まれています。

「TextFieldとユーザー入力」で何を学びますか?

Composeでユーザーのテキスト入力を受け取ります。 ブラウザで直接実行するハンズオンコードでAndroid Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Android Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのAndroid Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。

「TextFieldとユーザー入力」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このAndroid Academyレッスンでコードを書いて実行できますか?

はい。すべてのAndroid Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. TextFieldとユーザー入力
  2. フォーム状態の管理
  3. 入力値のバリデーション
  4. キーボードのオプションとアクション
← Android Academyに戻る