#跟着若城学鸿蒙# HarmonyOS NEXT学习之Select案例二:高级选择与样式定制
·

一、案例介绍
本案例将展示Select组件的高级选择功能和自定义样式实现,通过一个商品筛选器的示例,展示如何构建功能丰富、外观精美的选择器界面。
二、代码实现
@Entry
@Component
struct SelectAdvancedExample {
@State selectedCategory: string = ''
@State selectedSubCategory: string = ''
@State selectedBrand: string = ''
@State selectedPrice: string = ''
@State categoryIndex: number = -1
@State subCategoryIndex: number = -1
@State brandIndex: number = -1
@State priceIndex: number = -1
@State subCategories: string[] = []
@State brands: string[] = []
private readonly categories: string[] = ['手机数码', '电脑办公', '家用电器', '服装鞋包']
private readonly categoryMap: Map<string, string[]> = new Map([
['手机数码', ['手机', '平板', '智能手表', '耳机']],
['电脑办公', ['笔记本', '台式机', '显示器', '打印机']],
['家用电器', ['电视', '空调', '冰箱', '洗衣机']],
['服装鞋包', ['男装', '女装', '运动', '箱包']]
])
private readonly brandMap: Map<string, string[]> = new Map([
['手机', ['华为', '苹果', '小米', '三星']],
['平板', ['华为', '苹果', '小米', '联想']],
['笔记本', ['联想', '华为', '戴尔', '惠普']],
['电视', ['海信', '小米', 'TCL', '索尼']]
])
private readonly priceRanges: string[] = [
'0-1000元',
'1000-3000元',
'3000-5000元',
'5000元以上'
]
build() {
Column() {
Text('商品筛选')
.fontSize(24)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 20 })
// 一级分类
this.SelectItem(
'商品分类:',
this.selectedCategory || '请选择分类',
this.categories,
this.categoryIndex,
(index: number) => {
this.categoryIndex = index
this.selectedCategory = this.categories[index]
// 更新二级分类
this.subCategories = this.categoryMap.get(this.selectedCategory) || []
// 重置后续选择
this.resetSubSelections()
}
)
// 二级分类
if (this.subCategories.length > 0) {
this.SelectItem(
'子分类:',
this.selectedSubCategory || '请选择子分类',
this.subCategories,
this.subCategoryIndex,
(index: number) => {
this.subCategoryIndex = index
this.selectedSubCategory = this.subCategories[index]
// 更新品牌
this.brands = this.brandMap.get(this.selectedSubCategory) || []
// 重置后续选择
this.resetBrandAndPrice()
}
)
}
// 品牌选择
if (this.brands.length > 0) {
this.SelectItem(
'品牌:',
this.selectedBrand || '请选择品牌',
this.brands,
this.brandIndex,
(index: number) => {
this.brandIndex = index
this.selectedBrand = this.brands[index]
this.resetPrice()
}
)
}
// 价格区间
if (this.selectedBrand) {
this.SelectItem(
'价格区间:',
this.selectedPrice || '请选择价格区间',
this.priceRanges,
this.priceIndex,
(index: number) => {
this.priceIndex = index
this.selectedPrice = this.priceRanges[index]
}
)
}
// 筛选结果预览
if (this.hasSelection()) {
Column() {
Text('已选条件')
.fontSize(18)
.fontWeight(FontWeight.Bold)
.margin({ top: 30, bottom: 10 })
Row() {
if (this.selectedCategory) {
this.FilterTag(this.selectedCategory)
}
if (this.selectedSubCategory) {
this.FilterTag(this.selectedSubCategory)
}
}
.width('100%')
.margin({ bottom: 8 })
Row() {
if (this.selectedBrand) {
this.FilterTag(this.selectedBrand)
}
if (this.selectedPrice) {
this.FilterTag(this.selectedPrice)
}
}
.width('100%')
}
.width('100%')
.padding(16)
.backgroundColor('#F5F5F5')
.borderRadius(8)
.margin({ top: 20 })
}
// 确认按钮
Button('确认筛选')
.width('100%')
.height(50)
.backgroundColor('#007DFF')
.borderRadius(8)
.fontSize(18)
.fontColor(Color.White)
.margin({ top: 20 })
.enabled(this.isFilterComplete())
.opacity(this.isFilterComplete() ? 1 : 0.5)
.onClick(() => {
this.applyFilter()
})
}
.width('100%')
.height('100%')
.padding(16)
}
@Builder
SelectItem(label: string, value: string, options: string[], selectedIndex: number, onSelectCallback: (index: number) => void) {
Row() {
Text(label)
.fontSize(16)
.width(100)
Select({
value: value,
selected: selectedIndex,
options: options
})
.width('70%')
.height(40)
.backgroundColor(selectedIndex === -1 ? '#F5F5F5' : '#E6F2FF')
.borderRadius(8)
.fontColor(selectedIndex === -1 ? '#999999' : '#007DFF')
.onSelect((index: number) => {
onSelectCallback(index)
})
}
.width('100%')
.margin({ bottom: 20 })
}
@Builder
FilterTag(text: string) {
Text(text)
.fontSize(14)
.backgroundColor('#E6F2FF')
.fontColor('#007DFF')
.padding({ left: 12, right: 12, top: 6, bottom: 6 })
.borderRadius(16)
.margin({ right: 8 })
}
private resetSubSelections() {
this.selectedSubCategory = ''
this.selectedBrand = ''
this.selectedPrice = ''
this.subCategoryIndex = -1
this.brandIndex = -1
this.priceIndex = -1
this.brands = []
}
private resetBrandAndPrice() {
this.selectedBrand = ''
this.selectedPrice = ''
this.brandIndex = -1
this.priceIndex = -1
}
private resetPrice() {
this.selectedPrice = ''
this.priceIndex = -1
}
private hasSelection(): boolean {
return this.selectedCategory !== '' ||
this.selectedSubCategory !== '' ||
this.selectedBrand !== '' ||
this.selectedPrice !== ''
}
private isFilterComplete(): boolean {
return this.selectedCategory !== '' &&
this.selectedSubCategory !== '' &&
this.selectedBrand !== '' &&
this.selectedPrice !== ''
}
private applyFilter() {
const filterConditions = {
category: this.selectedCategory,
subCategory: this.selectedSubCategory,
brand: this.selectedBrand,
priceRange: this.selectedPrice
}
console.info('应用筛选条件:', JSON.stringify(filterConditions))
// 处理筛选逻辑
}
}
三、总结
本案例通过一个商品筛选器的示例,展示了 Select 组件的高级选择功能和自定义样式实现。通过配置 Select 组件的基本属性(如 value、selected、options 等),实现了标准的下拉选择功能。同时,通过自定义样式(如背景色、字体、圆角等),提升了下拉菜单的视觉效果。此外,通过事件监听(如 onSelect),实现了选项选中时的动态更新。
更多推荐


所有评论(0)