Skip to content

【Compose】TextFieldにClickEventを貼る

Posted on:2024年10月21日 at 20:00

備忘録。

目次

  1. 困ったこと
    1. 環境
  2. 結論
  3. enabledとcolorsプロパティを変更して見た目を整える
  4. TextFieldの上に透明なBoxを重ねてClickEventを奪う
  5. 参考文献

困ったこと

JetpackComposeを利用して開発を行う中で、TextFieldからDatePicker,TimePickerを呼び出したい場面に遭遇しました。
ただし、enabled=falseなどでTextFieldの見た目は変えたくありません。

環境

結論

以下の2つの戦略があります。

  1. enabled=falseを利用するうえでcolorsプロパティを変更して見た目を整える
  2. TextFieldの上に透明なBoxを重ねてClickEventを奪う

enabledとcolorsプロパティを変更して見た目を整える

enabled=falseにするとTextFieldのComposableにてclickableイベントを発火することが可能になります。
しかしそのままでは見た目が変わってしまうので、colorsプロパティを変更して見た目を調整します。

コード例は以下。supportingTextやLeadingIconなどを利用している場合、その色も指定する必要があります。

TextField(
    value = dateTimeString,
    label = { Text("日時") },
    enabled = false,
    colors = TextFieldDefaults.colors(
        disabledTextColor = MaterialTheme.colorScheme.onSurface,
        disabledLabelColor = MaterialTheme.colorScheme.onSurfaceVariant,
    ),
    modifier = Modifier
        .clickable { onClick() }
)

この方法だと毎回必要なcolorsプロパティを変更する必要があるためまぁまぁ面倒です。

TextFieldの上に透明なBoxを重ねてClickEventを奪う

シンプルな解決方法。
以下のようなComposableを用意してあげると便利です。

@Composable
private fun ReadonlyTextField(
    onClick: () -> Unit,
    content: @Composable () -> Unit
){
    Box {
        content()
        Box(modifier = Modifier
            .matchParentSize()
            .alpha(0f)
            .clickable { onClick() })
    }
}

こんな感じで利用できます。

@Composable
fun Hoge(){
	ReadonlyTextField(
		onClick = { openDateTimePicker() }
	) {
	    TextField(
	        ...
	    )
	}
}

けっこう脳筋な解決方法ですが、いちいちプロパティを設定する必要がないためお手軽です。

参考文献

android - Detect click in Compose TextField - Stack Overflow

JetPack Compose: DatePicker-TextField | by Max Großmann | Medium