kotlin 自定义搜索下拉框

系列文章目录

提示:最注意的一点我会标红
例如:使用OutlinedTextField 自定义组件



前言

提示:我这里是工作中自己的需要的可以自己改:

例如:随着不断的发展,我们的需求也越来越多了。


提示:以下是本篇文章正文内容,下面案例可供参考

一、自定义组件

示例:创建一个 kt文件。


import android.util.Log
import android.widget.Toast
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.DropdownMenu
import androidx.compose.material.DropdownMenuItem
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.*
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.PopupProperties
import androidx.lifecycle.viewmodel.compose.viewModel
import cn.dianbobo.dbb.modules.auditionscreen.controllers.AuditionController
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

@OptIn(ExperimentalMaterial3Api::class, ExperimentalComposeUiApi::class)
@Suppress("FunctionName")
@Composable
fun TextBoxComponents(
    placeholder: String,
    mobileValue: String,
    onMobileValueChange: (String) -> Unit,
    onTextChange: ((String) -> Unit)? = null,  // 添加的可选回调
    plus86Text: String,
    isNumericInput: Boolean = false, // 默认为false,除非明确指定
    whetherToSearch : Boolean = false,
) {
    val context = LocalContext.current
    val coroutineScope = rememberCoroutineScope()
    val auditionController: AuditionController = viewModel()
    val searchResults by auditionController.searchResults.observeAsState(initial = emptyList())
    var expanded by remember { mutableStateOf(false) } // 下拉框的展开状态
    Box(
        modifier = Modifier.fillMaxWidth()
    ) {
        OutlinedTextField(
            value = mobileValue,

            onValueChange = {

                coroutineScope.launch {
                    auditionController.getSearch(name = it)
                    delay(200)
                    auditionController.focusRequester.requestFocus()
                }
                 onTextChange?.invoke(it)
                if (!isNumericInput) {
                    // 如果是字符串输入,限制长度为10
                    if (it.length <= 10) {
                        onMobileValueChange(it)
                    }else{
                        Toast.makeText(context, "内容不得超过十个", Toast.LENGTH_SHORT).show()
                    }
                } else {
                    // 如果是数字输入,先检查格式,然后限制长度为4
                    if (it.matches(Regex("^\\d{0,6}(\\.\\d{0,2})?$"))) {
                        onMobileValueChange(it)
                    }else{
                        Toast.makeText(context, "价格限制在六位数", Toast.LENGTH_SHORT).show()
                    }
                }
            },
            placeholder = {
                Text(
                    placeholder,
                    modifier = Modifier.padding(start = 1.dp),
                    style = TextStyle(
                        color = Color.Gray,
                        fontSize = 13.sp
                    )
                )
            },
            singleLine = true,
            modifier = Modifier.fillMaxWidth().padding(start = 70.dp).focusRequester(auditionController.focusRequester).onFocusChanged { focusState ->
                if (focusState.isFocused) {
                    Log.d("获取到焦点","打")
                }
            },
            keyboardOptions = KeyboardOptions.Default.copy(
                imeAction = ImeAction.Next,
                keyboardType = if (isNumericInput) KeyboardType.Number else KeyboardType.Text
            ),
            keyboardActions = KeyboardActions(onNext = { /* focus on next field */ }),
            colors = TextFieldDefaults.outlinedTextFieldColors(
                focusedBorderColor = Color.Transparent,
                unfocusedBorderColor = Color.Transparent
            ),
        )
        LaunchedEffect(searchResults) {
            expanded = searchResults.isNotEmpty() && whetherToSearch
            if (expanded) {
                // 请求焦点
                auditionController.focusRequester.requestFocus()
            }
        }

        if (expanded) {
            if (searchResults.isNotEmpty() && whetherToSearch) {
                DropdownMenu(properties = PopupProperties(focusable = false),
                    expanded = expanded,
                    onDismissRequest = {
                        expanded =false
                    },
                    modifier = Modifier
                        .align(Alignment.Center)
                        .fillMaxWidth(0.8f)
                        .height(200.dp).padding(20.dp)
                ) {
                    searchResults.forEach { industry ->
                        DropdownMenuItem(onClick = {
                            expanded =false
                        }) {
                            Text(industry.name)
                        }
                    }
                }
            }
        }


        Text(
            plus86Text,
            modifier = Modifier
                .align(Alignment.CenterStart)
                .padding(start = 10.dp)
                .offset(y = 1.dp)
        )
    }
}

这个是最重要的 properties = PopupProperties(focusable = false 这个就是输入了之后然后不会失去焦点

二、使用步骤

代码如下(示例):

TextBoxComponents(
                placeholder = "示例:美食",
                mobileValue = auditionController.industry.value,
                onMobileValueChange = { auditionController.industry.value = it },
                onTextChange = {
                    Log.d("TextBoxComponent", "文本变化: $it")
                    expanded = true// 当文本不为空时展开下拉框

                },
                plus86Text = "类目",
                whetherToSearch=true
            )

2.演示

图(示例):

在这里插入图片描述
输入一个字就会去调用接口进行展示

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杰哥力挽狂澜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值