Jetpack ComposeのTextField基本的な機能・デザイン関係まとめ

# TextFieldデザインまとめ

## デフォルトのデザインが

ちょっとAndroidアプリを作る用事があってJetpack Composeを使ったんですが、TextFieldを使ってみてデフォルトのデザインが~~気にくわない~~アプリ上での配置にそぐわない気がしたので、弄った知識をメモっておくことにしました。

## 環境

- Intellij IDEA 2022.1.2 Community Edition

```gradle:build.gradle(:app)
dependencies {
    /*中略*/
    implementation 'androidx.activity:activity-compose:1.3.0'
    implementation 'androidx.compose.ui:ui-tooling:1.0.0'
    implementation 'androidx.compose.material:material:1.0.1'
}
```

## 基本

### TextField

シンプルなテキストフィールドです。あの下線だけついてるようなやつ。
![textfield_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705544/e0625419-bd0e-0830-614e-f2ee39adc95f.jpeg)

### OutlinedTextField

周囲を囲まれたテキストフィールドです。多分ログイン画面の入力とかで使えそう
![outlined.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705544/caa54105-0c1b-2b52-ec85-62e91afc647c.jpeg)

## デザイン

### 下線のみ (TextField)

デフォルト以上にシンプルなので、ほかの`Composable`と組み合わせてもうるさくなりにくいです。
しかしこれだけだと逆にこれがテキストフィールドであるとわかりにくいので、後の検索ボックスの例のように他と組み合わせて使う形になると思います。
![textfield_underline.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705544/400d1182-4ab5-cc90-999f-b059acfbf9a6.jpeg)![textfield_underline2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705544/0c3421ae-cd81-aa4b-67b6-527bea78f18a.jpeg)

```kotlin
val text = remember{ mutableStateOf("") }
TextField(
    value = text.value,
    onValueChange = {text.value=it},
    //以下注目
    colors = TextFieldDefaults.textFieldColors(
        backgroundColor = Color.Transparent
    )
)
```

引数`colors`の型は`TextFieldColors(interface)`です。`TextFiedlDefaults`クラスからいい感じに取得できます。

`textFieldColors`関数ですが、おびただしい数の引数( **計21個、全てが色の指定** )を受けるので、やろうと思えばえげつないほどカラフルな配色も可能と思われます。私は遠慮しておきます

### 入力ヒント

入力内容に関してユーザーに提示するテキストを表示できます。
一文字でもフィールドに文字が入っている場合表示されなくなります。
![placeholder.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705544/c65a9aaa-60b9-2b28-7fde-99487ff166d7.jpeg)![placeholder2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705544/5d18e687-7abe-b380-a249-ee74f5a5ff1a.jpeg)

```kotlin
TextField(
    value = text.value,
    onValueChange = {text.value=it},
    //以下注目
    placeholder = { Text(text = "入力内容に関するテキスト")}
)
```

`hint`とかじゃなくて`placeholder`ですね。

### ラベル(ヒントっぽいけど入力した後は避けてくれる)
![label.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705544/6cb6c4ce-b44b-26d8-5870-a68652ac92cf.jpeg)![label2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705544/60ee3f6a-f18f-42d7-edb2-733e9ff3b71b.jpeg)

```kotlin
TextField(
    value = text.value,
    onValueChange = {text.value=it},
    //以下注目
    label = { Text(text = "入力内容に関するテキスト")}
)
```

入力したら避けてくれるヒントです。`placeholder`を`label`で置き換えればよいです。

Outlinedに使うとなんかいい感じに避けてくれます。
![label_outline.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705544/84b9279a-d499-c46e-e450-0bc3cba34dcd.jpeg)![label_outline2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705544/01dda330-671f-3f1a-7f9f-bce885489ae8.jpeg)

### アイコン

アイコンを指定できます。前につくものと、後ろにつくものがあります
![icon.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705544/35b1525b-24b9-349b-0b10-413977a75abc.jpeg)
```kotlin
TextField(
    value = text.value,
    onValueChange = {text.value=it},
    //前につくアイコン
    leadingIcon = {
        Icon(
            Icons.Sharp.Done,
            contentDescription = null,
            tint = colorResource(
                id = R.color.design_default_color_primary
            )
        )
    },
    //後ろにつくアイコン
    trailingIcon = {
        Icon(
            Icons.Sharp.Close,
            contentDescription = null,
            tint = colorResource(
                id = R.color.design_default_color_primary
            )
        )
    }
)
```
前付き`leadingIcon` 後付き`trailingIcon`にそれぞれ指定します。
アイコンはコンポーザブルを呼んでるだけなのでやろうと思えば代わりにテキストの表示もできるかも。(推奨はされないでしょうが)

あとで検索フィールドへの使用例をご紹介します。

### パスワード系

入力した文字の表示を別の文字に置き換えます。
![transform.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705544/9b87002b-0f97-a992-c58d-ecf1b47b06ad.jpeg)
```kotlin
TextField(
    value = text.value,
    onValueChange = {text.value=it},
    //以下注目
    visualTransformation = PasswordVisualTransformation()
)
```

画像では"mypassword"と入力したはずですが、内容を盗み見ることができません。

引数`visualTransformation : VisualTransformation`を使用します。
パスワードについては`PasswordVisualTransformation`クラスがあるので使わせてもらいましょう。
代わりに`VisualTransformation((AnnotatedString)->TransformedText)`を使用すれば明示的に置換手法の指定もできます。

## 使用例：パスワード入力 (OutliedTextField)

![password.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705544/dabbe0f3-795c-da80-3e40-a27324372136.jpeg)
```kotlin
OutlinedTextField(
    value = text.value,
    onValueChange = {text.value=it},
    label = { Text(text = "パスワード")},
    visualTransformation = PasswordVisualTransformation()
)
```
これだけだけどかなりそれっぽいです。

## 使用例：検索ボックス (TextField)
![searchbox.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705544/3eea13fb-49b8-12a0-51f9-8043b14e5ad2.jpeg)

```kotlin
TextField(
    value = text.value,
    onValueChange = {text.value=it},
    placeholder = { Text(text = "検索")},
    leadingIcon = {
        Icon(
            Icons.Sharp.Search,
            contentDescription = null,
            tint = colorResource(
                id = R.color.design_default_color_primary
            )
        )
    },
    trailingIcon = {
        Icon(
            Icons.Sharp.Close,
            contentDescription = "×",
            tint = colorResource(
                id = R.color.design_default_color_primary
            )
        )
    },
    colors = TextFieldDefaults.textFieldColors(
        backgroundColor = Color.Transparent
    )
)
```

ちょっと長ったらしいけどやってることは上で紹介したものを組み合わせただけです。
個人的お気に入り

## 参考

https://www.youtube.com/watch?v=6D57qSBmPLA

こちらの動画にはもっと詳しい(グラデーションを使ったデザインなど)が紹介されています。