Open1
TextFieldの汎用化

なぜ汎用化なのか?
今回はこんなUIを考えました。
- 1行目:タイトル
- 2行目:入力例
- 3行目:入力するところ
- 4行目:スペース
これをコンポーザブル関数にすると。。。
@Composable
fun TestScreen(
modifier: Modifier = Modifier,
){
Text(text = "■表情", style= MaterialTheme.typography.titleLarge)
Text(text = "例)ぷんぷん怒っている")
TextField(
value = uiState.personState.emotion,
onValueChange = { viewModel.updateUiState({ copy(personState = personState.copy(emotion = it)) }) },
label = { Text(text=stringResource(R.string.person_emotion)) },
modifier = modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(dimensionResource(R.string.person_emotion)))
}
これ1つだけだったら問題ないと思います。
でも同じようなコンポーザブルが30個とかあったら。。。?
コピペするのもいいかなとは思いますが、後で2行目と3行目を入れ替えよう!とかスペースいらね!みたいな変更があった時に、「あ~~~~~~めんどくせ!」となります。
なので、汎用化して1個修正したら全部に適用!としておきます。
個別部分を引数にする
以下プログラムのうち、個別になる部分を決めていきます。
太字部分がそれにあたります。
Text(text = "■表情", style= MaterialTheme.typography.titleLarge)
Text(text = "例)ぷんぷん怒っている")
TextField(
value = uiState.personState.emotion,
onValueChange = { viewModel.updateUiState({ copy(personState = personState.copy(emotion = it)) }) },
label = { Text(text=stringResource(R.string.person_emotion)) },
modifier = modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(dimensionResource(R.string.person_emotion)))
変数化すると、こう
Text(text = "■$title", style= MaterialTheme.typography.titleLarge)
Text(text = "例)$example")
TextField(
value = value,
onValueChange = onValueChange,
label = { Text(text=stringResource(labelResId)) },
modifier = modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(dimensionResource(R.dimen.p_medium)))
新しい関数を作って、変数部分を引数に割り当てます。
@Composable
fun LabeledTextField(
modifier: Modifier = Modifier,
+ title:String,
+ example:String,
+ value: String,
+ onValueChange: (String) -> Unit,
+ labelResId:Int,
){
Text(text = "■$title", style= MaterialTheme.typography.titleLarge)
Text(text = "例)$example")
TextField(
value = value,
onValueChange = onValueChange,
label = { Text(text=stringResource(labelResId)) },
modifier = modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(dimensionResource(R.dimen.p_medium)))
}
UIからの呼び出し
@Composable
fun TestScreen(
modifier: Modifier = Modifier,
){
LabeledTextField(
title = "■表情",
example = "ぷんぷん怒っている",
value = uiState.personState.emotion,
onValueChange = { viewModel.updateUiState({ copy(personState = personState.copy(emotion = it)) }) },
labelResId = R.string.person_emotion,
)
}
UI側では、引数に値を割り当てるだけになったので、設定も楽ですね!