compose Android 自定义输入框

180 阅读1分钟

BasicTextField使用,官方布局解释

62FF9532-1A07-4c97-BFB2-D60E369862F4.png


定义一个String searchText 过程中跟随布局事件变化

var searchText by remember { mutableStateOf("") }

定义一个监听,完成searchText赋值

value = searchText,
onValueChange = {
            searchText = it
        }

添加某个必要提交

interactionSource = remember { MutableInteractionSource() }

定义键盘按钮类型为搜索

keyboardOptions = KeyboardOptions(
    keyboardType = KeyboardType.Text, imeAction = ImeAction.Search
)

定义搜索对应点击事件

keyboardActions = KeyboardActions(onSearch = {
    onSearch(searchText)
})

定义游标颜色跟随主题

cursorBrush = SolidColor(MaterialTheme.colorScheme.primary)

decorationBox中定义主体部分,Row定义横向布局和背景样式background填充样式border边框样式,左边搜索Icon,右边清除Icon并且内容为空时隐藏不空时显示,中间内容部分用Text文本触发动作回调innerTextField()

效果展示

Screenshot_20231011_092213_ComposePart1.jpg

完整代码

@Composable
fun SearchButton(onSearch: (String) -> Unit) {
    var searchText by remember { mutableStateOf("") }
    BasicTextField(
        value = searchText,
        onValueChange = {
            searchText = it
//            onSearch(searchText)
        },
        interactionSource = remember { MutableInteractionSource() },
        enabled = true,
        singleLine = true,
        keyboardOptions = KeyboardOptions(
            keyboardType = KeyboardType.Text, imeAction = ImeAction.Search
        ),
        keyboardActions = KeyboardActions(onSearch = {
            onSearch(searchText)
        }),
        cursorBrush = SolidColor(MaterialTheme.colorScheme.primary),
        decorationBox = { innerTextField ->
            Row(
                modifier = Modifier
                    .height(40.dp)
                    .fillMaxWidth()
                    .background(Color(0xFFf5f5f5), RoundedCornerShape(20.dp))
//                    .border(
//                        border = BorderStroke(
//                            0.5.dp, Color.Transparent
//                        )
//                    )
                ,verticalAlignment = CenterVertically
            ) {

                Image(imageVector = Icons.Default.Search,
                    contentDescription = "",
                    contentScale = ContentScale.None,
                    alignment = Center,
                    colorFilter = ColorFilter.tint(Color.Gray),
                    modifier = Modifier
                        .padding(horizontal = 14.dp)
                        .clickable {
                            onSearch(searchText)
                        })
                Box(
                    contentAlignment = Alignment.CenterStart, modifier = Modifier.weight(1f)
                ) {
                    Text(
                        text = if (TextUtils.isEmpty(searchText)) "搜索" else "",
                        modifier = Modifier.fillMaxWidth(),
                        style = LocalTextStyle.current.copy(
                            textAlign = TextAlign.Start,
                            color = if (TextUtils.isEmpty(searchText)) Color.Gray else Color.Black,
                            fontSize = TextUnit(14f, TextUnitType.Sp)
                        )
                    )
                    innerTextField()
                }
                if (!TextUtils.isEmpty(searchText)) {
                    Image(imageVector = Icons.Default.Clear,
                        contentDescription = "",
                        contentScale = ContentScale.None,
                        alignment = Center,
                        colorFilter = ColorFilter.tint(Color.Gray),
                        modifier = Modifier
                            .padding(horizontal = 14.dp)
                            .clickable {
                                searchText = ""
//                                onSearch(searchText)
                            })
                }
            }
        },
        modifier = Modifier
            .fillMaxWidth()
            .wrapContentHeight()
            .padding(start = 8.dp, end = 8.dp, top = 8.dp)
    )
}