You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter日历应用如何基于分类索引动态展示对应图标替换原有双图标逻辑

第一步:数据层适配

首先把Category类的定义抽成独立的公共文件(比如category.dart),避免两个页面重复定义,同时给ColorPicker增加必要的入参:分类列表、当前选中的分类索引、选中后的回调。

第二步:核心逻辑修改

把原来硬编码的两种圆形图标替换为分类对应的自定义图标,保留选中状态的视觉区分,推荐两种可选的选中标识方案,可按需选择:

  • 方案1:选中时图标为对应分类颜色,未选中时图标为灰色,同时选中项加后缀勾选标记
  • 方案2:选中时给图标套一层对应颜色的圆形背景,未选中时无背景,和原有视觉风格保持一致

第三步:完整修改代码示例

公共category.dart代码

class Category {
  String eventCategory;
  IconData eventIcon;
  Color categoryColor; // 补充分类对应颜色字段,替换原来的_colorCollection
  Category(this.eventCategory, this.eventIcon, this.categoryColor);
}

// 预设分类可以放在这里也可以放在你的Calendar.dart里
List<Category> defaultCategories = [
  Category('生产力', Icons.add_to_queue, Colors.blue),
  Category('自我提升', Icons.bolt_rounded, Colors.orange),
  Category('待办任务', Icons.check, Colors.green),
];

修改后的color-picker.dart代码

注意:原有_ColorPicker是私有类,跨文件调用需要去掉开头的下划线改为公开类

// 先引入Category的公共定义
import 'category.dart';

class ColorPicker extends StatefulWidget {
  final List<Category> categories; // 传入分类列表
  final int selectedIndex; // 传入当前选中的分类索引
  final Function(int index) onSelect; // 选中后的回调

  const ColorPicker({
    super.key,
    required this.categories,
    required this.selectedIndex,
    required this.onSelect,
  });

  @override
  State<ColorPicker> createState() => _ColorPickerState();
}

class _ColorPickerState extends State<ColorPicker> {
  late int _tempSelectedIndex;

  @override
  void initState() {
    super.initState();
    _tempSelectedIndex = widget.selectedIndex;
  }

  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      content: Container(
          width: double.maxFinite,
          child: ListView.builder(
            padding: const EdgeInsets.all(0),
            itemCount: widget.categories.length,
            itemBuilder: (BuildContext context, int index) {
              final currentCategory = widget.categories[index];
              final isSelected = index == _tempSelectedIndex;
              return ListTile(
                contentPadding: const EdgeInsets.all(0),
                // 方案1:直接显示分类图标,通过颜色区分选中状态
                leading: Icon(
                  currentCategory.eventIcon, // 直接用分类对应的自定义图标
                  color: isSelected ? currentCategory.categoryColor : Colors.grey,
                  size: 28,
                ),
                // 方案2:保留原有圆形背景样式,替换内部图标,二选一即可
                // leading: Stack(
                //   alignment: Alignment.center,
                //   children: [
                //     Icon(
                //       isSelected ? Icons.lens : Icons.trip_origin,
                //       color: currentCategory.categoryColor,
                //       size: 32,
                //     ),
                //     Icon(
                //       currentCategory.eventIcon,
                //       color: Colors.white,
                //       size: 18,
                //     ),
                //   ],
                // ),
                title: Text(currentCategory.eventCategory),
                trailing: isSelected ? const Icon(Icons.check, color: Colors.green) : null, // 选中项加勾选标记
                onTap: () {
                  setState(() {
                    _tempSelectedIndex = index;
                  });
                  widget.onSelect(index);
                  Future.delayed(const Duration(milliseconds: 200), () {
                    Navigator.pop(context);
                  });
                },
              );
            },
          )),
    );
  }
}

Calendar.dart中调用示例

// 打开分类选择器的逻辑
void openCategoryPicker() {
  showDialog(
    context: context,
    builder: (context) => ColorPicker(
      categories: _categories, // 你自己定义的分类列表
      selectedIndex: _selectedCategoryIndex, // 当前选中的分类索引
      onSelect: (index) {
        setState(() {
          _selectedCategoryIndex = index;
        });
      },
    ),
  );
}

内容的提问来源于stack exchange,提问作者RoRo Studio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 12:48:04