当前位置: 首页 > news >正文

Compose笔记(三十七)--FilterChip

        这一节主要了解一下Compose中的FilterChip,在Compose中,FilterChip是Material Design组件库提供的一种交互式芯片,主要用于提供多选或单选的筛选条件。简单总结如下

API
selected:控制Chip是否选中
onClick:点击事件回调
label:Chip显示的文本内容
leadingIcon:左侧图标
trailingIcon: 右侧图标(常用于显示选中状态)
colors:控制Chip在不同状态下的颜色
border:边框样式
shape:形状配置
enabled:是否可用状态

场景:
1. 内容筛选,适用于需要按类别、属性过滤列表/网格内容的场景
2. 标签式分类选择,适用于需要按标签对内容进行分类的场景,支持单选或多选
3. 状态切换型筛选,适用于需要按“状态”过滤内容的场景,状态通常是二元或少量固定选项

栗子:

import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Done
import androidx.compose.material.icons.filled.Home
import androidx.compose.material3.FilterChip
import androidx.compose.material3.FilterChipDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier@Composable
fun TestFilterChipExample() {var selected by remember { mutableStateOf(false) }FilterChip(     selected = selected,onClick = { selected = !selected },label = { Text("Filter chip") },leadingIcon =         if (selected) {             {Icon( imageVector = Icons. Filled.Done,contentDescription = "Localized Description",modifier = Modifier.size(FilterChipDefaults. IconSize))             }         } else {             {Icon( imageVector = Icons. Filled.Home,contentDescription = "Localized description",modifier = Modifier. size(FilterChipDefaults. IconSize))}} )
}
import android.annotation.SuppressLint
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Done
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.spdata class Article(val id: String,val title: String,val tags: List<String>
)@SuppressLint("UnrememberedMutableState")
@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class)
@Composable
fun TestTagFilterExample() {val articles = remember {listOf(Article("1", "Jetpack Compose基础", listOf("Android", "Compose")),Article("2", "Kotlin协程", listOf("Kotlin", "协程")),Article("3", "Material3设计规范", listOf("Android", "UI")),Article("4", "Compose状态管理", listOf("Android", "Compose", "状态管理")))}val allTags = remember {articles.flatMap { it.tags }.distinct().toMutableStateList()}var selectedTags by remember { mutableStateOf(setOf<String>()) }var newTag by remember { mutableStateOf("") }val filteredArticles by derivedStateOf {if (selectedTags.isEmpty()) articleselse articles.filter { article ->article.tags.any { selectedTags.contains(it) }}}Column(modifier = Modifier.fillMaxSize()) {Text(text = "文章标签筛选",fontSize = 20.sp,fontWeight = FontWeight.Bold,modifier = Modifier.padding(16.dp))Row(modifier = Modifier.padding(16.dp),verticalAlignment = Alignment.CenterVertically) {OutlinedTextField(value = newTag,onValueChange = { newTag = it },label = { Text("添加新标签") },modifier = Modifier.weight(1f),singleLine = true,keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),keyboardActions = KeyboardActions(onDone = {if (newTag.isNotBlank() && !allTags.contains(newTag)) {allTags.add(newTag)newTag = ""}}))Button(onClick = {if (newTag.isNotBlank() && !allTags.contains(newTag)) {allTags.add(newTag)newTag = ""}},modifier = Modifier.padding(start = 8.dp),enabled = newTag.isNotBlank()) {Text("添加")}}Text(text = "标签列表",fontWeight = FontWeight.Medium,modifier = Modifier.padding(16.dp, 8.dp, 16.dp, 0.dp))FlowRow(modifier = Modifier.padding(12.dp),horizontalArrangement = Arrangement.spacedBy(8.dp),verticalArrangement = Arrangement.spacedBy(8.dp)) {allTags.forEach { tag ->val isSelected = selectedTags.contains(tag)FilterChip(selected = isSelected,onClick = {selectedTags = if (isSelected) {selectedTags - tag} else {selectedTags + tag}},label = { Text(tag) },leadingIcon = if (isSelected) {{Icon(imageVector = Icons.Filled.Done,contentDescription = "已选择",modifier = Modifier.size(FilterChipDefaults.IconSize))}} else null,colors = FilterChipDefaults.filterChipColors(containerColor = if (isSelected)MaterialTheme.colorScheme.primaryContainerelse MaterialTheme.colorScheme.surface,labelColor = if (isSelected)MaterialTheme.colorScheme.onPrimaryContainerelse MaterialTheme.colorScheme.onSurface,iconColor = MaterialTheme.colorScheme.onPrimaryContainer),border = FilterChipDefaults.filterChipBorder(borderColor = MaterialTheme.colorScheme.outline,borderWidth = 1.dp,enabled = true,selected = isSelected,selectedBorderColor = MaterialTheme.colorScheme.primary,disabledBorderColor = MaterialTheme.colorScheme.outline.copy(alpha = 0.38f),disabledSelectedBorderColor = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.38f),selectedBorderWidth = 1.dp),shape = MaterialTheme.shapes.small)}}Text(text = "筛选结果 (${filteredArticles.size})",fontWeight = FontWeight.Medium,modifier = Modifier.padding(16.dp))LazyColumn(modifier = Modifier.weight(1f)) {items(filteredArticles) { article ->Card(modifier = Modifier.fillMaxWidth().padding(12.dp),elevation = CardDefaults.cardElevation(defaultElevation = 2.dp)) {Column(modifier = Modifier.padding(16.dp)) {Text(text = article.title,fontWeight = FontWeight.Bold,fontSize = 16.sp)Spacer(modifier = Modifier.height(8.dp))FlowRow(horizontalArrangement = Arrangement.spacedBy(4.dp)) {article.tags.forEach { tag ->Box(modifier = Modifier.background(if (selectedTags.contains(tag))MaterialTheme.colorScheme.primaryContainerelse MaterialTheme.colorScheme.surfaceVariant,shape = MaterialTheme.shapes.small).padding(4.dp, 2.dp)) {Text(text = tag,fontSize = 12.sp,color = if (selectedTags.contains(tag))MaterialTheme.colorScheme.onPrimaryContainerelse MaterialTheme.colorScheme.onSurfaceVariant)}}}}}}}}
}

注意:
1 明确“选中即生效”的设计原则,避免将其用于“需要批量选择后统一生效”的场景,选中状态变化时,应立即更新筛选结果
2 区分“单选”和“多选”场景,多选场景:允许同时选中多个芯片,筛选逻辑为 “满足任一条件”;单选场景:选中新芯片时,需自动取消同组其他芯片的选中状态。
3 正确处理FilterChipDefaults参数,Material 3的FilterChip参数严格,需注意border参数需指定所有状态(选中/未选中/禁用)的边框样式,colors参数需区分容器色(containerColor)和内容色(labelColor),

http://www.dtcms.com/a/289822.html

相关文章:

  • TVLT:无文本视觉-语言Transformer
  • c++ duiLib 显示一个简单的窗口
  • AMD处理器 5700G 矿卡RX580-8G 打英雄联盟怎么样
  • 洛谷 P10287 [GESP样题 七级] 最长不下降子序列-普及/提高-
  • 《P2680 [NOIP 2015 提高组] 运输计划》
  • 【66】MFC入门到精通——(CComboBox)下拉框选项顺序与添加顺序不一致
  • 前端静态资源免费cdn服务推荐
  • Dify极简部署手册
  • 30天打好数模基础-逻辑回归讲解
  • 7-大语言模型—指令理解:指令微调训练+模型微调
  • 【算法训练营Day15】二叉树part5
  • 编程研发工作日记
  • 050_Set接口(HashSet / TreeSet / LinkedHashSet)
  • 力扣面试150题--搜索插入位置
  • 某市公安局视频图像信息综合应用平台设计方案Word(446页)
  • AI产品经理面试宝典第40天:用户反馈处理与技术应用面试题与答法
  • 多校2+多校1的遗珠
  • 信道相关系数
  • 安装kali时出现“安装步骤失败“如何解决及后续软件安装
  • Python自动化测试项目实战
  • QT项目-仿QQ音乐的音乐播放器(第一节)
  • 什么是卡贴???
  • 国产电钢琴性价比实战选购指南
  • Python 虚拟环境与构建工具全景指南:功能介绍与对比分析
  • 基于Transformer的心理健康对话系统:从零构建AI心理咨询助手
  • 【全球甲烷估算模型】简化一箱模型(1-box model)
  • MySQL中的排序和分页
  • [simdjson] 实现不同CPU调度 | 自动硬件适配的抽象
  • C 语言经典编程题实战:从基础算法到趣味问题全解析
  • MybatisPlus-09.核心功能-IService开发复杂业务接口