ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

HarmonyOS应用<奇妙科学乐园>开发第51篇:分类筛选标签——Scroll横向滚动与选中态

HarmonyOS应用<奇妙科学乐园>开发第51篇:分类筛选标签——Scroll横向滚动与选中态 引言在上一篇文章中我们完成了科普知识列表页 Topics 中搜索栏组件的完整拆解从 TextInput 的属性配置到 onChange 事件监听再到 500ms 防抖定时器的进阶优化。搜索栏下方紧跟着的一排可横滑分类标签是搜索与列表之间承上启下的关键交互组件。分类筛选标签在移动端应用中极为常见微信通讯录的字母索引、淘宝商品分类的横向标签栏、B站视频的分区筛选——本质上都是同一个交互模式一组互斥的选项用户点击后切换当前激活项列表内容随之刷新。在《奇妙科学乐园》中这排标签承载着太空探索、自然世界、海洋生物等六大科学分类外加一个固定的全部标签构成完整的分类筛选体系。本文将深入解析 Topics 页面中分类筛选标签的完整实现涵盖 Scroll 横向滚动的配置技巧、全部标签与动态分类标签的布局编排、选中/未选中两种视觉状态的条件渲染以及搜索与分类筛选的联动逻辑。源码仓库https://atomgit.com/2301_79280419/WonderSciencePark 学习目标完成本文后你将能够✅ 掌握 Scroll 组件横向滚动的配置scrollable、scrollBar、margin 技巧✅ 理解 Row 嵌套在 Scroll 中的水平排列布局原理✅ 实现选中/未选中两种视觉状态的条件渲染backgroundColor、fontColor、border✅ 掌握全部静态标签与 ForEach 动态分类标签的混排方案✅ 理解分类切换时清空搜索关键词的联动设计✅ 掌握 ForEach 的 keyGenerator 函数与数据稳定性✅ 了解 Scroll 横向滚动中右侧留白与边缘对齐的处理技巧 需求分析分类标签在页面中的位置科普知识列表页 Topics ├── 页面标题栏Row: 科普知识设置图标 ├── 搜索栏Row: 搜索图标TextInput ├── 分类筛选标签Scroll:RowColumn标签组 ← 本文主角 │ ├── 全部静态标签 │ ├── 太空探索动态标签 │ ├── 自然世界动态标签 │ ├── 海洋生物动态标签 │ ├── 科技发明动态标签 │ ├── 人体奥秘动态标签 │ └── 天气现象动态标签 ├── 文章计数共 X 篇文章 ├── 文章卡片列表LazyForEachTopicCard └── 空状态/错误状态功能模块设计模块功能描述技术要点横向滚动容器超出屏幕宽度的标签支持横向滑动Scroll scrollable(ScrollDirection.Horizontal)全部标签固定的第一个标签点击显示全部文章静态 Column 条件样式分类标签组从 categories 数据动态生成的标签列表ForEach Category 数据模型选中高亮当前选中标签的主题色填充 白色文字三元表达式条件渲染样式未选中样式白色背景 深色文字 灰色边框默认样式配置搜索联动切换分类时自动清空搜索关键词selectCategory 方法骨架占位加载中显示灰色矩形条条件渲染 骨架色分类切换的数据流用户点击分类标签 ↓selectCategory(categoryId)↓ ├── 更新 currentCategory categoryId ├── 清空 searchKeyword ← 联动清空搜索 └── 调用 loadTopics() ↓getTopicsByCategory(currentCategory)↓ topicDataSource.setData(topicList) ↓ LazyForEach 刷新列表️ 核心实现步骤1: Scroll 横向滚动容器配置功能说明当分类标签数量较多、总宽度超出屏幕时需要支持横向滑动。HarmonyOS 中通过Scroll组件的scrollable(ScrollDirection.Horizontal)属性实现水平滚动。本步骤聚焦于 Scroll 容器本身的关键配置。完整代码//entry/src/main/ets/pages/Topics.ets//分类标签区域——Scroll 横向滚动容器//分类标签 Scroll() { Row() {//全部标签 ForEach 分类标签 } .padding({ right:16});//右侧内边距保证最后一个标签不贴边 } .scrollable(ScrollDirection.Horizontal)//开启横向滚动 .scrollBar(BarState.Off)//隐藏滚动条 .margin({ left:0, right: -16, bottom:4});代码解析1. 横向滚动方向设置Scroll(){ ... }.scrollable(ScrollDirection.Horizontal)原理/说明:ScrollDirection.Horizontal枚举值指定滚动方向为水平Scroll 的默认滚动方向是垂直Vertical必须显式指定为 Horizontal子容器Row的内容总宽度超过 Scroll 自身宽度时才会出现滚动2. 隐藏滚动条.scrollBar(BarState.Off)原理/说明:BarState.Off完全隐藏滚动条保持界面简洁横向标签栏通常不需要显示滚动条用户通过手指滑动即可感知可滚动对于面向儿童的应用隐藏滚动条还能减少视觉干扰3. 右侧留白与边缘对齐// Row 内部右侧内边距.padding({right:16});// Scroll 外部右边距为 -16.margin({left:0,right: -16,bottom:4});原理/说明:Row 的padding({ right: 16 })确保最后一个标签右侧有 16vp 的间距Scroll 的margin({ right: -16 })使用负边距让 Scroll 的滚动区域向右延伸 16vp两者的配合效果最后一个标签可以滚动到屏幕右边缘而不是停留在距右侧 16vp 的位置margin({ bottom: 4 })为标签栏与下方列表之间增加 4vp 的间距负边距的对齐效果对比:❌ 无负边距right:0: ┌─────────────────────────────┐ │[全部][太空][自然][海洋]│ ← 最后标签距右边缘16vp └─────────────────────────────┘ ✅ 有负边距right: -16: ┌─────────────────────────────┐ │[全部][太空][自然][海洋]│← 可继续滚动 → └─────────────────────────────┘ 滑动后: ┌─────────────────────────────┐[太空][自然][海洋][科技]│ ← 最后标签可以贴齐右边缘 └─────────────────────────────┘步骤2: 全部标签——静态标签的条件样式功能说明全部标签是分类筛选栏的第一个固定标签不参与 ForEach 动态渲染。它的categoryId固定为all点击后显示所有分类的文章。选中与未选中两种状态通过三元表达式切换背景色、文字颜色和边框颜色。完整代码// entry/src/main/ets/pages/Topics.ets// 全部标签——静态渲染Column() { Text(全部) .fontSize(14) .fontWeight(FontWeight.Medium) .fontColor(this.currentCategory all? ThemeColors.TEXT_WHITE : ThemeColors.TEXT_PRIMARY ); } .padding({ left:16, right:16, top:8, bottom:8}) .backgroundColor(this.currentCategory all? ThemeColors.PRIMARY : ThemeColors.BG_PRIMARY ) .borderRadius(16) .border({ width:1, color:this.currentCategory all? ThemeColors.PRIMARY :#e0e0e0}) .onClick(() {this.selectCategory(all); });代码解析1. 文字颜色条件切换.fontColor( this.currentCategory all? ThemeColors.TEXT_WHITE//选中白色文字#ffffff: ThemeColors.TEXT_PRIMARY//未选中深色文字#333333)原理/说明:this.currentCategory all判断当前分类是否为全部选中时使用ThemeColors.TEXT_WHITE白色与主题色背景形成对比未选中时使用ThemeColors.TEXT_PRIMARY深色保证在白色背景上的可读性三元表达式的两个分支都引用 ThemeColors 常量不使用硬编码色值2. 背景色条件切换.backgroundColor( this.currentCategory all? ThemeColors.PRIMARY//选中主题色#ff6b6b: ThemeColors.BG_PRIMARY//未选中白色#ffffff)原理/说明:选中时背景变为主题色珊瑚红 #ff6b6b形成醒目的高亮效果未选中时背景为白色与页面背景融为一体主题色ThemeColors.PRIMARY是应用的品牌色贯穿所有页面的强调元素3. 边框颜色条件切换.border({width:1,color:this.currentCategoryall? ThemeColors.PRIMARY// 选中主题色边框与背景融为一体:#e0e0e0// 未选中浅灰边框勾勒轮廓})原理/说明:选中时边框色与背景色相同都是 PRIMARY视觉上边框消失未选中时使用浅灰边框#e0e0e0勾勒出标签的轮廓边框宽度固定为 1vp既清晰又不显厚重4. 点击事件.onClick((){ this.selectCategory(all); })原理/说明:点击全部标签时调用selectCategory(all)方法该方法会更新 currentCategory、清空搜索关键词、刷新列表后文详述步骤3: 动态分类标签——ForEach 遍历渲染功能说明全部标签之后的分类标签太空探索、自然世界、海洋生物等由ForEach根据 categories 数据动态生成。每个标签的选中态判断依据是this.currentCategory category.id。标签之间通过margin({ left: 8 })控制间距。完整代码//entry/src/main/ets/pages/Topics.ets//动态分类标签——ForEach 遍历 ForEach(this.categories, (category: Category) { Column(){ Text(category.name).fontSize(14).fontWeight(FontWeight.Medium).fontColor( this.currentCategory category.id ? ThemeColors.TEXT_WHITE : ThemeColors.TEXT_PRIMARY ); }.padding({ left: 16, right: 16, top: 8, bottom: 8 }).backgroundColor( this.currentCategory category.id ? ThemeColors.PRIMARY : ThemeColors.BG_PRIMARY ).borderRadius(16).border({ width: 1, color: this.currentCategory category.id ? ThemeColors.PRIMARY : #e0e0e0 }).margin({ left: 8 })//标签之间的间距.onClick(() { this.selectCategory(category.id); }); },(category: Category) category.id);代码解析1. ForEach 的数据源与 keyGeneratorForEach(this.categories,// 数据源Category 数组(category: Category) { ... },// 子项生成函数(category: Category) category.id// key 生成函数);原理/说明:第一个参数this.categories是从scienceData.getAllCategories()获取的分类数据数组第二个参数是每个分类标签的 UI 生成函数参数category为当前遍历到的分类对象第三个参数是 key 生成函数使用category.id如 space、nature作为唯一标识key 必须唯一且稳定避免 ForEach 在数据更新时错误地复用或重建组件2. 动态标签与全部标签的样式一致性// 全部标签的选中判断this.currentCategory all// 动态标签的选中判断this.currentCategory category.id原理/说明:两种标签的样式属性fontSize、fontWeight、padding、borderRadius完全一致唯一的区别是选中判断条件all vs category.id这种一致性保证了视觉上的统一感用户不会感知到全部和分类标签是不同的组件3. 标签间距处理.margin({ left:8})//动态标签才有左边距原理/说明:全部标签是第一个标签不需要左边距每个动态标签通过margin({ left: 8 })与前一个标签保持 8vp 的间距这种第一个无间距、后续有间距的模式是标签栏的常见做法如果用 Row 的space: 8属性全部标签右侧也会有 8vp 间距效果不如 margin 精确步骤4: 选中态 vs 未选中态——完整样式对照功能说明每个分类标签有两种视觉状态通过this.currentCategory xxx的三元表达式进行切换。以下是对两种状态下所有样式属性的完整对照。完整代码//entry/src/main/ets/pages/Topics.ets//标签样式配置汇总//选中态以全部为例currentCategory all Column() { Text(全部) .fontSize(14) .fontWeight(FontWeight.Medium) .fontColor(ThemeColors.TEXT_WHITE);//白色文字 } .padding({ left:16, right:16, top:8, bottom:8}) .backgroundColor(ThemeColors.PRIMARY)//主题色背景#ff6b6b.borderRadius(16)//圆角 .border({ width:1, color: ThemeColors.PRIMARY });//主题色边框//未选中态currentCategory !all Column() { Text(全部) .fontSize(14) .fontWeight(FontWeight.Medium) .fontColor(ThemeColors.TEXT_PRIMARY);//深色文字#333} .padding({ left:16, right:16, top:8, bottom:8}) .backgroundColor(ThemeColors.BG_PRIMARY)//白色背景 .borderRadius(16) .border({ width:1, color:#e0e0e0});//浅灰边框代码解析样式属性对照表属性选中态未选中态视觉效果fontColorTEXT_WHITE (#fff)TEXT_PRIMARY (#333)白字 vs 深色字backgroundColorPRIMARY (#ff6b6b)BG_PRIMARY (#fff)珊瑚红 vs 白色border.colorPRIMARY (#ff6b6b)#e0e0e0与背景同色 vs 浅灰fontSize1414一致fontWeightMediumMedium一致padding16/16/8/816/16/8/8一致borderRadius1616一致视觉效果示意:选中态: 未选中态:┌──────────────┐ ┌──────────────┐ │ ● 全 部 │ ← 珊瑚红底 │ 太空探索 │ ← 白色底 │ 白色文字 │ 白色字 │ 深色文字 │ 深色字 └──────────────┘ 主题色边框 └──────────────┘ 灰色边框原理/说明:选中态的边框色与背景色相同都是 PRIMARY边框在视觉上隐形未选中态的浅灰边框勾勒出标签轮廓与白色背景形成柔和的区分两种状态切换时背景色、文字色、边框色三个属性同时变化形成明确的视觉反馈步骤5: selectCategory 方法——分类切换与搜索联动功能说明selectCategory方法是分类标签点击事件的统一处理入口。它完成三件事更新当前分类、清空搜索关键词、刷新文章列表。这种切分类清搜索的联动设计避免了用户同时处于搜索模式和分类模式的混乱状态。完整代码//entry/src/main/ets/pages/Topics.ets//分类切换方法 selectCategory(categoryId: string) {//第一步更新当前选中的分类 this.currentCategory categoryId;//第二步清空搜索关键词退出搜索模式 this.searchKeyword ;//第三步按新分类重新加载文章列表 this.loadTopics(); }代码解析1. 三步操作的设计逻辑this.currentCategory categoryId;// 状态更新this.searchKeyword ;// 状态清理this.loadTopics();// 数据刷新原理/说明:this.currentCategory categoryId将组件的分类状态更新为用户点击的分类 IDthis.searchKeyword 清空搜索关键词确保从搜索模式切换回分类模式this.loadTopics()触发列表刷新因为 searchKeyword 为空会走getTopicsByCategory路径2. 搜索与分类的互斥关系loadTopics() {if(this.searchKeyword this.searchKeyword.trim() !) {// 搜索模式忽略分类this.topicList scienceData.searchTopics(this.searchKeyword); }else{// 分类模式按分类过滤this.topicList scienceData.getTopicsByCategory(this.currentCategory); }this.topicDataSource.setData(this.topicList); }原理/说明:搜索模式和分类模式通过searchKeyword是否为空来区分有搜索词时搜索结果覆盖分类筛选搜索优先无搜索词时按currentCategory过滤selectCategory中清空searchKeyword确保切回分类模式3. 交互流程示意初始状态: currentCategoryall, searchKeyword↓ 点击海洋生物selectCategory(ocean)↓ currentCategoryocean, searchKeyword↓loadTopics()→ getTopicsByCategory(ocean) ↓ 列表显示: 仅海洋生物分类的文章 用户在搜索栏输入太阳↓ onChange searchKeyword太阳↓loadTopics()→ searchTopics(太阳) ↓ 列表显示: 标题或分类名含太阳的文章跨分类 用户点击自然世界标签 ↓selectCategory(nature)↓ currentCategorynature, searchKeyword← 搜索被清空 ↓loadTopics()→ getTopicsByCategory(nature) ↓ 列表显示: 仅自然世界分类的文章步骤6: aboutToUpdate 中的外部分类切换功能说明当用户从首页点击分类图标进入科普列表时首页通过AppStorage.setOrCreate(topicsCategory, category.id)传递初始分类 ID。Topics 组件通过Prop initialCategory接收这个值在aboutToUpdate生命周期中检测变化并触发分类切换。完整代码// entry/src/main/ets/pages/Topics.ets// 外部分类切换检测PropinitialCategory: string all;StatecurrentCategory: string all; aboutToUpdate() {// 检测外部传入的 initialCategory 是否发生变化// 且仅在非搜索状态下响应避免覆盖用户的搜索操作if(this.initialCategory this.initialCategory !this.currentCategory this.searchKeyword ) {this.currentCategory this.initialCategory;if(scienceData.getIsInitialized()) {this.loadTopics(); } } }代码解析1. 三个条件的组合判断if(this.initialCategory this.initialCategory !this.currentCategory this.searchKeyword )条件作用说明this.initialCategory非空检查确保有传入的分类 IDthis.initialCategory ! this.currentCategory变化检测避免重复加载相同分类this.searchKeyword 搜索状态检查用户正在搜索时不打断原理/说明:第一个条件排除initialCategory为空或 undefined 的情况第二个条件防止相同分类重复加载的无效操作第三个条件是最关键的——如果用户正在搜索中从首页点击分类进来不应该覆盖用户的搜索状态三个条件缺一不可共同保证了外部切换的安全性和用户体验2. 首页传递分类 ID 的方式//entry/src/main/ets/pages/Index.ets//首页点击分类图标时 goToCategory(category: Category): void {//通过 AppStorage 通知 MainTabs 切换到科普 Tab AppStorage.setOrCreatestring(switchToTab,topics);//传递分类 ID 给 Topics 组件 AppStorage.setOrCreatestring(topicsCategory, category.id); }原理/说明:首页不直接使用 router 跳转而是通过 AppStorage 传递消息switchToTab通知 MainTabs 切换到科普知识 TabtopicsCategory传递目标分类 IDTopics 组件的Prop initialCategory绑定了这个 AppStorage 值步骤7: 骨架屏中的分类标签占位功能说明在数据加载过程中分类标签区域显示一组灰色的矩形占位条模拟真实标签的尺寸和间距给用户一个标签即将出现的视觉预期。完整代码//entry/src/main/ets/pages/Topics.ets//加载中状态——分类标签骨架if(this.isLoading) { Column() {//...搜索栏骨架...//分类标签骨架 Row({ space:8}) { ForEach([1,2,3,4], (_: number) { Column() .width(56) .height(32) .backgroundColor(SKELETON_COLOR)//#e2e8f0.borderRadius(16); }, (_: number, index: number) index.toString()); } .width(100%) .margin({ bottom:16}); } }代码解析1. 骨架标签的尺寸设计属性骨架占位真实标签说明width56自适应padding 1616文字宽度骨架取中等宽度height32padding 88文字高度 ≈ 32高度一致borderRadius1616完全一致space8margin left: 8间距一致原理/说明:骨架标签使用固定的 56x32 尺寸接近真实标签的平均大小生成 4 个骨架标签与实际 61 个标签数量接近不需要完全一致borderRadius 与真实标签保持一致16确保加载完成后圆角过渡自然Row({ space: 8 })使用 Row 的 space 属性简化骨架间距设置⚠️ 常见问题与解决方案问题1: Scroll 横向滚动不生效现象:分类标签设置了scrollable(ScrollDirection.Horizontal)但内容无法横向滑动。错误代码:// ❌ 错误: 使用 Column 作为 Scroll 的子容器Column 是垂直布局Scroll(){Column(){ForEach(this.categories, (category: Category) {...}); } } .scrollable(ScrollDirection.Horizontal);正确代码:// ✅ 正确: 使用 Row 作为 Scroll 的子容器Row 是水平布局Scroll(){Row(){ForEach(this.categories, (category: Category) {...}); } } .scrollable(ScrollDirection.Horizontal);规则/建议:横向滚动的 Scroll 必须搭配 Row 作为直接子容器Row 会将子元素水平排列当总宽度超出 Scroll 宽度时触发滚动如果使用 Column子元素会垂直排列横向滚动自然无法生效问题2: 最后一个标签无法滚动到屏幕右侧现象:横向滑动到最右侧时最后一个标签仍然距屏幕右边缘有一段空白无法完全显示。错误代码:// ❌ 错误: 没有处理右侧留白最后一个标签被卡住Scroll() { Row() {// 标签们...}// 缺少右侧内边距}.scrollable(ScrollDirection.Horizontal).scrollBar(BarState.Off);正确代码:// ✅ 正确: Row 内部 padding Scroll 外部负 margin 配合Scroll(){ Row() {// 标签们...}.padding({right:16});// Row 内部右侧留白}.scrollable(ScrollDirection.Horizontal).scrollBar(BarState.Off).margin({right: -16});// Scroll 负边距补偿规则/建议:Row 的padding({ right: 16 })确保最后一个标签右侧有呼吸空间Scroll 的margin({ right: -16 })用负边距扩展滚动区域两者数值必须一致如都是 16才能正确抵消这是横向标签栏的标准配方建议直接复用问题3: ForEach key 不稳定导致标签闪烁现象:切换分类后标签出现短暂的闪烁或位置错乱ForEach 错误地重建了组件。错误代码:// ❌ 错误: 使用 index 作为 keyForEach(this.categories, (category: Category) {// 标签 UI},(category: Category,index:number) index.toString());正确代码:// ✅ 正确: 使用 category.id 作为唯一且稳定的 keyForEach(this.categories, (category: Category) {// 标签 UI},(category: Category) category.id);规则/建议:ForEach 的 key 必须是数据项的唯一标识不能使用数组索引使用 index 作为 key 时如果数组顺序变化如排序、过滤会导致组件错误复用category.id是每个分类的唯一标识如 space、nature不会随数据变化而改变key 的类型应与原始数据类型一致string 返回 string不需要 toString()问题4: 标签选中状态不同步现象:点击分类标签后视觉上标签没有变为选中态或者多个标签同时显示为选中态。错误代码:// ❌ 错误: 每个标签维护自己的 isSelected 状态ComponentstructCategoryTag { State isSelected: boolean false; category: Category; build(){Column(){Text(this.category.name).fontColor(this.isSelected? #fff : #333); } .backgroundColor(this.isSelected? #ff6b6b : #fff).onClick(() { this.isSelected true;// 只更新自己的状态}); } }正确代码:// ✅ 正确: 父组件统一管理 currentCategory子标签通过比较判断选中态// 父组件StatecurrentCategory: string all;// 子标签通过 this.currentCategory category.id 判断.fontColor(this.currentCategory category.id ? ThemeColors.TEXT_WHITE : ThemeColors.TEXT_PRIMARY ) .backgroundColor(this.currentCategory category.id ? ThemeColors.PRIMARY : ThemeColors.BG_PRIMARY )规则/建议:互斥选项组的状态应该由父组件统一管理而不是每个子项各自维护使用currentCategory单一状态变量 条件表达式是最简洁的互斥实现避免分散状态每个标签一个 isSelected导致的同步问题问题5: 切换分类后搜索栏仍显示旧关键词现象:用户先搜索太阳然后点击自然世界分类列表正确切换了但搜索栏中仍然显示太阳二字。错误代码:// ❌ 错误: 切换分类时没有清空搜索关键词selectCategory(categoryId:string) {this.currentCategory categoryId;// 缺少: this.searchKeyword ;this.loadTopics(); }正确代码:// ✅ 正确: 切换分类时同步清空搜索关键词selectCategory(categoryId: string) {this.currentCategory categoryId;this.searchKeyword ;// 清空搜索状态this.loadTopics(); }规则/建议:分类和搜索是两种互斥的筛选模式切换时必须清理另一种模式的状态如果使用State searchKeyword绑定 TextInput清空变量后输入框会自动同步清空建议在 selectCategory 方法中显式清空而非依赖 TextInput 的双向绑定 本章小结核心知识点本文详细讲解了科普知识列表页中分类筛选标签的完整实现主要包括1. Scroll 横向滚动配置scrollable(ScrollDirection.Horizontal)开启水平滚动scrollBar(BarState.Off)隐藏滚动条保持界面简洁Rowpadding({ right: 16 }) Scrollmargin({ right: -16 })的右侧留白配方2. 选中态条件渲染this.currentCategory xxx三元表达式驱动三种样式属性切换选中态主题色背景 白色文字 主题色边框未选中态白色背景 深色文字 灰色边框3. 分类与搜索的联动设计selectCategory 方法中同时更新分类状态和清空搜索关键词loadTopics 根据 searchKeyword 是否为空决定走搜索路径还是分类路径aboutToUpdate 中三个条件组合检测外部分类切换最佳实践总结✅Scroll 横向滚动容器Scroll(){ Row() {// 标签内容}.padding({right:16}); }.scrollable(ScrollDirection.Horizontal).scrollBar(BarState.Off).margin({left:0, right: -16, bottom:4});✅选中态条件样式Column(){ Text(category.name).fontSize(14).fontWeight(FontWeight.Medium).fontColor(this.currentCategory category.id ? ThemeColors.TEXT_WHITE : ThemeColors.TEXT_PRIMARY); }.padding({ left: 16, right: 16, top: 8, bottom: 8 }).backgroundColor(this.currentCategory category.id ? ThemeColors.PRIMARY : ThemeColors.BG_PRIMARY).borderRadius(16).border({ width: 1, color: this.currentCategory category.id ? ThemeColors.PRIMARY : #e0e0e0 });✅分类搜索联动selectCategory(categoryId: string) {this.currentCategory categoryId;this.searchKeyword ;this.loadTopics(); }下一步预告在下一篇文章中我们将: 深入拆解首页 Index 头部区域的 linearGradient 渐变实现 解析 135 度角度渐变与品牌色配色方案的设计思路✂️ 探讨 clip(true) 圆角裁剪在渐变背景中的应用 相关链接项目源码:Atomgit仓库 提示: 建议结合项目源码中entry/src/main/ets/pages/Topics.ets的分类标签区域和entry/src/main/ets/constants/AppConstants.ets的 ThemeColors 定义对照阅读理解主题色体系与条件渲染的配合方式!
返回列表