Compose for Desktop & Jetpack Compose 下拉搜索框实现

一个下拉搜索框,可根据输入的内容(直接输入内容或拼音首字母)自动更新下拉搜索框。此代码使用IDEA的Compose for Desktop编写,可无缝移植到Android Jetpack Compose(亲测直接复制粘贴配一下第三方拼音包就能在Android上跑起来,黄色版Android Studio),真正的 "write once, run anywhere", Windows+Android上可以直接对标苹果的SwiftUI。(在Android上运行还是要调整一下字体之类的参数,不然看着有点难受)。

import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.Text
import androidx.compose.material.TextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import com.github.promeg.pinyinhelper.Pinyin
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.em

class TestUI {

    @Composable
    fun SearchList(list: MutableList<String>) {
        /**
         * 输入框内的值
         */
        var value by remember { mutableStateOf("") }

        /**
         * 原始数据
         */
        var testList = list

        /**
         * 输入的汉字列表生成的汉字-拼音首字母组合表
         */
        var hanZiPinYinList: MutableMap<String, String> = mutableMapOf()
        testList.forEach { hanZiPinYinList[it] = pinyinFirstCharacter(it) }
        var dropList: MutableList<String> = mutableListOf()
        var dropListRemember by remember { mutableStateOf(dropList) }

        /**
         * 点击下拉列表选项的标志位
         * 如果用户未点击下拉列表选项,值为0,已经点击,值为1
         * 值为1时,将搜索框赋值为已点击选项的值,且输入框失去焦点
         */
        var clicked by remember { mutableStateOf(0) }
        if (clicked == 1) {
            LocalFocusManager.current.clearFocus()
        }

        Column(
            modifier = Modifier.size(150.dp, 300.dp)
        ) {
            TextField(
                value = value,
                onValueChange = { it ->
                    //开始输入,输入框获得焦点
                    clicked = 0
                    value = it
                    //输入后重新计算下拉列表
                    dropListRemember.clear()
                    if (value.length != 0)
                    //同时匹配内容和首字母
                        hanZiPinYinList.forEach {
                            if (it.value.startsWith(value) || it.key.startsWith(value)) dropListRemember.add(
                                it.key
                            )
                        }
                },
                modifier = Modifier
                    .fillMaxWidth()
                    .border(1.dp, Color.Gray),
                textStyle = TextStyle(
                    color = Color.Black,
                    fontSize = 1.4.em,
                    fontWeight = FontWeight.Bold,
                )
            )
            /**
             * 加载下拉列表
             */
            LazyColumn {
                items(dropListRemember) { item ->
                    Text(
                        item,
                        modifier = Modifier
                            .fillMaxWidth()
                            .border(1.dp, Color.Gray)
                            .clickable {
                                value = item
                                dropListRemember.clear()
                                //若点击选项,更新状态
                                clicked = 1
                            },
                        fontSize = 1.2.em
                    )
                }
            }
        }
    }

    /**
     * 汉字转拼音首字母,用tinypinyin实现
     */
    fun pinyinFirstCharacter(hanzi: String): String {
        if (hanzi == "") return ""
        else {
            var returnString = ""
            hanzi.forEach {
                returnString += Pinyin.toPinyin(it).toLowerCase()[0]
            }
            return returnString
        }
    }
}
复制代码
分类:
Android