kotlin - 如何垂直对齐文本字段中的文本和前导/尾随图标

标签 kotlin android-jetpack-compose compose-desktop

有没有办法将尾随/前导图标和文本设置在同一级别?默认情况下,它并不如下图所示。我尝试更改 TextField 中的 fontStyle 参数,但没有成功。文本显示高于图标

enter image description here

import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material.Icon
import androidx.compose.material.OutlinedTextField
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowForward
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.window.singleWindowApplication

fun main() = singleWindowApplication {
    var text by remember { mutableStateOf("TEXT") }
    
    OutlinedTextField(
        value = text,
        onValueChange = { text = it },
        modifier = Modifier.fillMaxWidth(),
        leadingIcon = {
            Icon(contentDescription = null,
                 imageVector = Icons.Default.ArrowForward)
        },
        trailingIcon = {
            Icon(contentDescription = null,
                 imageVector = Icons.Default.ArrowForward)
        })
}

最佳答案

有几种解决方案。对于桌面 Compose,请偏移图标。对于移动 Compose,调整基线。最后,只需创建一个自定义 TextField。

图标的底部可能有额外的填充。也可能是图标和文本始终与顶部对齐。您可以将图标替换为没有底部填充的图标或将图标向上移动。您可以看出图标正在影响垂直对齐,因为如果您注释掉图标,文本就会垂直居中。您也可以尝试减小图标的大小。

在桌面 Compose 上,将图标向上移动:

OutlinedTextField(
     value = text,
     onValueChange = { text = it },
     modifier = Modifier.fillMaxWidth(),
     leadingIcon = {
          Icon(
                modifier = Modifier.offset(y = -3.dp),
                contentDescription = null,
                imageVector = Icons.Default.ArrowForward
          )
     },
     trailingIcon = {
          Icon(
                modifier = Modifier.offset(y = -3.dp),
                contentDescription = null,
                imageVector = Icons.Default.ArrowForward
          )
     })

在移动设备上,您可以调整文本的基线:

OutlinedTextField(
    value = text,
    textStyle = TextStyle(baselineShift = BaselineShift(-0.2f)),
    onValueChange = { text = it },
    modifier = Modifier.fillMaxWidth(),
    leadingIcon = {
        Icon(
            contentDescription = null,
            imageVector = Icons.Default.ArrowForward
        )
    },
    trailingIcon = {
        Icon(
            contentDescription = null,
            imageVector = Icons.Default.ArrowForward
        )
    })

这也是一个自定义 TextField:

class MainActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            CustomTextField(
                initialText = "cool",
                onValueChange = {

                },
                onLeftButtonClick = {

                },
                onRightButtonClick = {

                }
            )
        }
    }
}

@Composable
fun CustomTextField(
    initialText: String,
    onValueChange: (text: String) -> Unit,
    onLeftButtonClick: () -> Unit,
    onRightButtonClick: () -> Unit
) {

    var text by remember { mutableStateOf(initialText) }

    Row(
        modifier = Modifier

            .fillMaxWidth()
            .wrapContentSize()
            .background(color = Color.White, shape = RoundedCornerShape(8.dp))

            .border(width = 1.dp, shape = RoundedCornerShape(8.dp), color = Color(0xFF585858))
    ) {

        ConstraintLayout(
            modifier = Modifier.fillMaxWidth()
        ) {

            val (left, mid, right) = createRefs()

            IconButton(onClick = onLeftButtonClick,
                modifier = Modifier.constrainAs(left) {
                    start.linkTo(parent.start, margin = 10.dp)
                    top.linkTo(parent.top)
                    bottom.linkTo(parent.bottom)
                }) {
                Icon(
                    contentDescription = null,
                    imageVector = Icons.Default.ArrowForward,
                )
            }


            IconButton(onClick = onRightButtonClick,
                modifier = Modifier.constrainAs(right) {
                    end.linkTo(parent.end, margin = 10.dp)
                    top.linkTo(parent.top)
                    bottom.linkTo(parent.bottom)
                }) {
                Icon(
                    contentDescription = null,
                    imageVector = Icons.Default.ArrowForward,
                )
            }

            TextField(
                value = text,
                onValueChange = {
                    text = it
                    onValueChange(it)
                },
                colors = TextFieldDefaults.textFieldColors(
                    backgroundColor = Color.White
                ),
                modifier = Modifier
                    .offset(y = 4.dp)
                    .constrainAs(mid) {
                        start.linkTo(left.end, margin = 10.dp)
                        top.linkTo(parent.top)
                        end.linkTo(right.start, margin = 10.dp)
                        bottom.linkTo(parent.bottom)
                        width = Dimension.fillToConstraints
                    })
        }
    }

关于kotlin - 如何垂直对齐文本字段中的文本和前导/尾随图标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70129846/

相关文章:

rest - 节流或限制 Kotlin CoRoutine 计数

kotlin - 如何触发CompletableDeferred <String>的onAwait函数?

android - 如何使用 Jetpack Compose 请求权限?

kotlin - 我是否需要在@Composable 中使用 repeatOnLifecycle 扭曲热流的 collectAsState()?

kotlin - 如何在 Kotlin Compose 桌面中加载图像?

kotlin - 如何在 Kotlin Compose Desktop 中让 Enter 键移动焦点?

android - Kotlin Coroutines - 返回流的暂停函数永远运行

intellij-idea - Ktor - 从插件快速启动新项目抛出错误

kotlin - 如何从 Compose-Navigation 中的返回堆栈中删除可组合项