android Jetpack撰写减少TextField的高度

zwghvu4y  于 2022-11-27  发布在  Android
关注(0)|答案(5)|浏览(288)

我试图设计一个搜索栏,像谷歌搜索栏的高度降低。但输入文本被裁剪,也占位符文本。

TextField(
                value = searchText.value,
                singleLine = true,
                onValueChange = {
                    searchText.value = it
                },
                placeholder = { //placeholder text is also getting cropped
                   
                        Text(
                            text = "Search",
                            fontSize = 20.sp,
                        )
                    
                },
                textStyle = TextStyle(fontSize = 20.sp), // input text is getting cropped
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(vertical = 10.dp)
                    .height(45.dp), // Here I have decreased the height
                shape = RoundedCornerShape(22.dp),
                )

我的输入文本和占位符文本被裁剪了50%。如何解决?

rkttyhzu

rkttyhzu1#

我在使用TextField时遇到了同样的问题。显然,这是一个有精确填充的材质组件,这会导致文本裁剪(即使字体较小)。
结果如下:

正如注解建议的解决方案是使用BasicTextField,下面是代码:

@Composable
private fun CustomTextField(
modifier: Modifier = Modifier,
leadingIcon: (@Composable () -> Unit)? = null,
trailingIcon: (@Composable () -> Unit)? = null,
placeholderText: String = "Placeholder",
fontSize: TextUnit = MaterialTheme.typography.body2.fontSize
) {
var text by rememberSaveable { mutableStateOf("") }
BasicTextField(modifier = modifier
    .background(
        MaterialTheme.colors.surface,
        MaterialTheme.shapes.small,
    )
    .fillMaxWidth(),
    value = text,
    onValueChange = {
        text = it
    },
    singleLine = true,
    cursorBrush = SolidColor(MaterialTheme.colors.primary),
    textStyle = LocalTextStyle.current.copy(
        color = MaterialTheme.colors.onSurface,
        fontSize = fontSize
    ),
    decorationBox = { innerTextField ->
        Row(
            modifier,
            verticalAlignment = Alignment.CenterVertically
        ) {
            if (leadingIcon != null) leadingIcon()
            Box(Modifier.weight(1f)) {
                if (text.isEmpty()) Text(
                    placeholderText,
                    style = LocalTextStyle.current.copy(
                        color = MaterialTheme.colors.onSurface.copy(alpha = 0.3f),
                        fontSize = fontSize
                    )
                )
                innerTextField()
            }
            if (trailingIcon != null) trailingIcon()
        }
    }
)
}

用改变的背景形状调用它:

CustomTextField(
        leadingIcon = {
            Icon(
                Icons.Filled.Search,
                null,
                tint = LocalContentColor.current.copy(alpha = 0.3f)
            )
        },
        trailingIcon = null,
        modifier = Modifier
            .background(
                MaterialTheme.colors.surface,
                RoundedCornerShape(percent = 50)
            )
            .padding(4.dp)
            .height(20.dp),
        fontSize = 10.sp,
        placeholderText = "Search"
)
jqjz2hbq

jqjz2hbq2#

1.2.0开始,您可以将**TextFieldDecorationBoxBasicTextField配合使用。
在这里,您可以使用
contentPadding**属性来减少垂直填充:

val colors = TextFieldDefaults.textFieldColors()

BasicTextField(
    value = text,
    onValueChange = { text = it },
    textStyle = TextStyle(fontSize = 20.sp),
    modifier = Modifier
        .background(
            color = colors.backgroundColor(enabled).value,
            shape = RoundedCornerShape(22.dp) //rounded corners
        )
        .indicatorLine(
            enabled = enabled,
            isError = false,
            interactionSource = interactionSource,
            colors = colors,
            focusedIndicatorLineThickness = 0.dp,  //to hide the indicator line
            unfocusedIndicatorLineThickness = 0.dp //to hide the indicator line
        )
        .height(45.dp),

    interactionSource = interactionSource,
    enabled = enabled,
    singleLine = singleLine
) {
    TextFieldDefaults.TextFieldDecorationBox(
        value = text,
        innerTextField = it,
        singleLine = singleLine,
        enabled = enabled,
        visualTransformation = VisualTransformation.None,
        trailingIcon = { /* ... */ },
        placeholder = {
            Text(
                text = "Search",
                fontSize = 20.sp,
            )
        },
        interactionSource = interactionSource,
        // keep horizontal paddings but change the vertical
        contentPadding = TextFieldDefaults.textFieldWithoutLabelPadding(
            top = 0.dp, bottom = 0.dp
        )
    )
}

cgyqldqp

cgyqldqp3#

更简单的方法是对其进行缩放:

TextField(
        value = "",
        onValueChange = {},
        modifier = Modifier.scale(scaleY = 0.9F, scaleX = 1F),
    )
2w2cym1i

2w2cym1i4#

我稍微改进了@zoran代码,此代码具有完整BasicTextField参数。

@Composable
    fun SimpleTextField(
        value: String,
        onValueChange: (String) -> Unit,
        modifier: Modifier = Modifier,
        enabled: Boolean = true,
        readOnly: Boolean = false,
        textStyle: TextStyle = LocalTextStyle.current,
        leadingIcon: @Composable (() -> Unit)? = null,
        trailingIcon: @Composable (() -> Unit)? = null,
        visualTransformation: VisualTransformation = VisualTransformation.None,
        keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
        keyboardActions: KeyboardActions = KeyboardActions(),
        singleLine: Boolean = false,
        maxLines: Int = Int.MAX_VALUE,
        interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
        placeholderText: String = "",
        fontSize: TextUnit = MaterialTheme.typography.body2.fontSize,
        onTextLayout: (TextLayoutResult) -> Unit = {},
        cursorBrush: Brush = SolidColor(Color.Black),
    ) {
        BasicTextField(modifier = modifier
            .fillMaxWidth(),
            value = value,
            onValueChange = onValueChange,
            singleLine = singleLine,
            maxLines = maxLines,
            enabled = enabled,
            readOnly = readOnly,
            interactionSource = interactionSource,
            textStyle = textStyle,
            visualTransformation = visualTransformation,
            keyboardOptions = keyboardOptions,
            keyboardActions = keyboardActions,
            onTextLayout = onTextLayout,
            cursorBrush = cursorBrush,
            decorationBox = { innerTextField ->
                Row(
                    modifier,
                    verticalAlignment = Alignment.CenterVertically
                ) {
                    if (leadingIcon != null) leadingIcon()
                    Box(Modifier.weight(1f)) {
                        if (value.isEmpty()) Text(
                            placeholderText,
                            style = textStyle
                        )
                        innerTextField()
                    }
                    if (trailingIcon != null) trailingIcon()
                }
            }
        )
    }
cig3rfwq

cig3rfwq5#

由于某种原因,当您键入并清除所有文本,然后再次键入时,已接受的答案会崩溃。因此,我复制了TextField的实际实现,更改了高度并删除了填充。

@Composable
fun SearchTextField(
    value: String,
    onValueChange: (String) -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    readOnly: Boolean = false,
    textStyle: TextStyle = LocalTextStyle.current,
    label: @Composable (() -> Unit)? = null,
    placeholder: @Composable (() -> Unit)? = null,
    leadingIcon: @Composable (() -> Unit)? = null,
    trailingIcon: @Composable (() -> Unit)? = null,
    supportingText: @Composable (() -> Unit)? = null,
    isError: Boolean = false,
    visualTransformation: VisualTransformation = VisualTransformation.None,
    keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
    keyboardActions: KeyboardActions = KeyboardActions.Default,
    singleLine: Boolean = false,
    maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE,
    minLines: Int = 1,
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    shape: Shape = TextFieldDefaults.filledShape,
    colors: TextFieldColors = TextFieldDefaults.textFieldColors()
) {
// If color is not provided via the text style, use content color as a default
    val textColor = textStyle.color.takeOrElse {
        MaterialTheme.colorScheme.onSurface
    }
    val customTextSelectionColors = TextSelectionColors(
        handleColor = MaterialTheme.colorScheme.primary,
        backgroundColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.4f)
    )

    CompositionLocalProvider(LocalTextSelectionColors provides customTextSelectionColors) {
        @OptIn(ExperimentalMaterial3Api::class)
        (BasicTextField(
            value = value,
            modifier = modifier.height(40.dp),
            onValueChange = onValueChange,
            enabled = enabled,
            readOnly = readOnly,
            cursorBrush = SolidColor(MaterialTheme.colorScheme.primary),
            visualTransformation = visualTransformation,
            keyboardOptions = keyboardOptions,
            keyboardActions = keyboardActions,
            interactionSource = interactionSource,
            singleLine = singleLine,
            maxLines = maxLines,
            minLines = minLines,
            decorationBox = @Composable { innerTextField ->
                // places leading icon, text field with label and placeholder, trailing icon
                TextFieldDefaults.TextFieldDecorationBox(
                    value = value,
                    visualTransformation = visualTransformation,
                    innerTextField = innerTextField,
                    placeholder = placeholder,
                    label = label,
                    leadingIcon = leadingIcon,
                    trailingIcon = trailingIcon,
                    supportingText = supportingText,
                    shape = shape,
                    singleLine = singleLine,
                    enabled = enabled,
                    isError = isError,
                    interactionSource = interactionSource,
                    colors = colors,
                    contentPadding = PaddingValues(0.dp)
                )
            }
        ))
    }
}

相关问题