いわたんち

いわたんちは概念となりました

Jetpack Composeで高さを小さくしたTextFieldを作る

こんな感じにIcon、Text、Iconを表示したTextFieldを用意して高さを標準よりも少し小さくしたい場合の対応方法です。

f:id:iwata_n:20211014231136p:plain

こんな感じでModifier.heightで高さを標準よりも小さくすると

var text by remember { mutableStateOf("") }
TextField(
    modifier = Modifier.height(36.dp).background(Color.White),
    value = text,
    onValueChange = {
        text = it
    }
)

f:id:iwata_n:20211014230947p:plain

のようにテキストを入力できるエリアの高さが縮んでしまい入力がまともにできない状態になる。

そんなときは、BasicTextFieldを使って自前でpaddingを含まないTextFieldを用意してあげる。

fun SearchTextField(
    value: String,
    onValueChange: (String) -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    readOnly: Boolean = false,
    textStyle: TextStyle = TextStyle.Default,
    keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
    keyboardActions: KeyboardActions = KeyboardActions.Default,
    visualTransformation: VisualTransformation = VisualTransformation.None,
    onTextLayout: (TextLayoutResult) -> Unit = {},
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    cursorBrush: Brush = SolidColor(Color.Black),
) {
    BasicTextField(
        value = value,
        onValueChange = onValueChange,
        modifier = modifier
            .background(
                color = MaterialTheme.colors.surface,
                shape = RoundedCornerShape(6.dp)
            ),
        enabled = enabled,
        readOnly = readOnly,
        textStyle = textStyle.copy(
            color = MaterialTheme.colors.onSurface,
        ),
        keyboardOptions = keyboardOptions,
        keyboardActions = keyboardActions,
        visualTransformation = visualTransformation,
        onTextLayout = onTextLayout,
        interactionSource = interactionSource,
        cursorBrush = cursorBrush,
        singleLine = true,
        decorationBox = { innerTextField ->
            Row(
                verticalAlignment = Alignment.CenterVertically,
            ) {
                Icon(
                    Icons.Filled.Search,
                    contentDescription = "search",
                    tint = MaterialTheme.colors.onSurface,
                )
                Box(Modifier.weight(1f)) {
                    if (value.isEmpty()) {
                        Text(
                            text = "検索",
                            style = LocalTextStyle.current.copy(
                                color = MaterialTheme.colors.onSurface,
                            )
                        )
                    }
                    innerTextField()
                }
                Icon(
                    Icons.Filled.Mic,
                    contentDescription = "mic",
                    tint = MaterialTheme.colors.onSurface,
                )
            }
        }
    )
}

冒頭に上げた画像のようにちゃんと高さが小さくできるようになる。