Как удалить индикаторную строку TextField в Androidx Compose Material?

Я хочу удалить фиолетовую линию / индикатор (см. Следующее изображение) TextField. Возможно ли это, или я должен создать свой собственный TextField для этого?

4 ответа

Решение

Если вы используете TextField в этом вы можете дать activeColor к Color.Transparent

Заметка: activeColor не только для индикатора, это для нижнего индикатора метки и курсора

Пример:

    var text: String by mutableStateOf("")
    TextField(value = text, onValueChange = {
        text = it
    }, activeColor = Color.Transparent)

Согласно документу, activeColor является

activeColor цвет метки, нижнего индикатора и курсора, когда текстовое поле находится в фокусе

Если вы хотите использовать свой собственный, вы можете попробовать BaseTextField

Это было изменено в недавнем выпуске Jetpack Compose UI Beta 1.0.0-beta01, теперь вы можете передать

TextFieldDefaults с желаемыми цветами.

       colors = TextFieldDefaults.textFieldColors(
            focusedIndicatorColor = Color.Transparent,
            disabledIndicatorColor = Color.Transparent,
            unfocusedIndicatorColor = Color.Transparent,
            backgroundColor = Color.LightGray,
        )

пример

      TextField(
        value = searchText,
        onValueChange = { Log.d(HOME_COMPONENT, it) },
        label = { Text(text = "Search") },
        shape = RoundedCornerShape(10.dp),
        leadingIcon = {
            Image(
                painter = painterResource(id = R.drawable.ic_search),
                contentDescription = "search"
            )
        },
        colors = TextFieldDefaults.textFieldColors(
            focusedIndicatorColor = Color.Transparent,
            disabledIndicatorColor = Color.Transparent,
            unfocusedIndicatorColor = Color.Transparent,
            backgroundColor = Color.LightGray,
        )
    )

изображение:

или если вы хотите настроить компонент в соответствии с вашим UI / UX, используйте BasicTextField

      @Composable
fun ToolbarComponent() {
    var searchText by remember { mutableStateOf("") }
    Row(
        modifier = Modifier
            .padding(16.dp)
            .fillMaxWidth(), verticalAlignment = Alignment.CenterVertically
    ) {

        Icon(
            painter = painterResource(id = R.drawable.ic_search),
            contentDescription = "search",
            modifier = Modifier.size(20.dp),
            tint = iconTintColor
        )

        Spacer(modifier = Modifier.size(16.dp))

        BasicTextField(
            value = searchText,
            onValueChange = { searchText = it },
            modifier = Modifier
                .background(shape = RoundedCornerShape(10.dp), color = Color.LightGray)
                .fillMaxWidth()
                .padding(16.dp),
            decorationBox = {
                Text(text = "Search")
            }
        )
    }
}

С участием 1.0.0-alpha04линия индикатора строится с помощью Modifier.drawBehind и нет параметров для его настройки.

Обходной путь (но мне это не нравится!) Может быть впереди другой строки с цветом фона родительского макета.

Что-то вроде:

       var text by remember { mutableStateOf(TextFieldValue("Text")) }
val focusRequester = FocusRequester()
var isFocused by remember { mutableStateOf(false) }

TextField(
        value = text,
        modifier = Modifier.focusObserver { isFocused = it.isFocused }
                .then(
                Modifier.drawIndicatorLine(
                        lineWidth = when(isFocused) {
                            true -> 2.dp   //indicatorWidth = 2.dp if focused
                            false -> 1.dp  //indicatorWidth = 1.dp if unfocused
                        },
                        color = Color.White ) //background color
        ),
        onValueChange = {
            text = it
        },
        label = { Text("Label") },
 )

с участием:

       private fun Modifier.drawIndicatorLine(lineWidth: Dp, color: Color): Modifier {
    return drawInFront {
        val strokeWidth = lineWidth.value * density
        val y = size.height - strokeWidth / 2
        drawLine(
                color,
                Offset(0f, y),
                Offset(size.width, y),
                strokeWidth
        )
    }
}
/**
 * Draw into a [Canvas] in front the modified content.
 */
fun Modifier.drawInFront(
        onDraw: DrawScope.() -> Unit
) = this.then(DrawBackgroundModifier(onDraw))

private class DrawBackgroundModifier(
        val onDraw: DrawScope.() -> Unit
) : DrawModifier {
    override fun ContentDrawScope.draw() {
        drawContent()
        onDraw()
    }
}

На самом деле (версия альфа 7) это самая простая версия, которую я нашел для удаления Divider.

Набор activeColor и inactiveColor к Color.Transparent чтобы скрыть строку индикатора под TextField, в любом его состоянии.

Если добавить только inactiveColor к Color.Transparent, строка будет невидимой, только если TextField не сфокусирован

Добавить textStyle = TextStyle(color = Color.White) чтобы отображать цвет, независимо от того, находится ли TextField в фокусе или нет.

Это решение удалит строку, а также индикатор курсора. На данный момент это не лучший вариант, но на самом деле это альфа-версия Compose.

       TextField(
    value = MyValue,
    onValueChange = { },
    textStyle = TextStyle(color = Color.White),
    activeColor = Color.Transparent,
    inactiveColor = Color.Transparent,
    shape = RoundedCornerShape(20)
)