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

如何用Flutter Riverpod按日期差值过滤列表数据

使用Flutter Riverpod实现列表过滤逻辑

1. 定义过滤类型枚举

先创建枚举类标识四种过滤状态:

enum FilterType {
  all, // 显示全部数据
  next, // 剩余天数≥15
  almostDone, // 0 < 剩余天数 < 15
  done, // 剩余天数≤0
}

2. 创建过滤状态管理Provider

用StateProvider保存当前选中的过滤类型,默认显示全部:

final filterTypeProvider = StateProvider<FilterType>((ref) => FilterType.all);

3. 实现过滤数据Provider

假设你已有原始数据的Provider(比如originalDataProvider)和计算剩余天数的方法,直接实现核心过滤逻辑:

// 示例数据模型(替换成你实际的模型)
class Task {
  final String title;
  final DateTime targetDate;
  Task({required this.title, required this.targetDate});
}

// 原始数据源Provider(替换成你实际的数据源)
final originalDataProvider = Provider<List<Task>>((ref) {
  return [
    Task(title: "任务A", targetDate: DateTime.now().add(const Duration(days: 20))),
    Task(title: "任务B", targetDate: DateTime.now().add(const Duration(days: 10))),
    Task(title: "任务C", targetDate: DateTime.now().subtract(const Duration(days: 5))),
  ];
});

// 复用你已实现的日期差计算方法
int calculateRemainingDays(DateTime targetDate) {
  final now = DateTime.now();
  return targetDate.difference(now).inDays;
}

// 核心过滤数据Provider
final filteredDataProvider = Provider<List<Task>>((ref) {
  final rawData = ref.watch(originalDataProvider);
  final currentFilter = ref.watch(filterTypeProvider);

  switch (currentFilter) {
    case FilterType.all:
      return rawData;
    case FilterType.next:
      return rawData.where((task) {
        final remaining = calculateRemainingDays(task.targetDate);
        return remaining >= 15;
      }).toList();
    case FilterType.almostDone:
      return rawData.where((task) {
        final remaining = calculateRemainingDays(task.targetDate);
        return remaining > 0 && remaining < 15;
      }).toList();
    case FilterType.done:
      return rawData.where((task) {
        final remaining = calculateRemainingDays(task.targetDate);
        return remaining <= 0;
      }).toList();
  }
});

4. 在UI中应用过滤逻辑

结合ListView.builder和过滤切换控件实现完整UI:

class FilteredTaskList extends ConsumerWidget {
  const FilteredTaskList({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final filteredTasks = ref.watch(filteredDataProvider);
    final currentFilter = ref.watch(filterTypeProvider);

    return Scaffold(
      appBar: AppBar(
        title: const Text("任务列表"),
        actions: [
          DropdownButton<FilterType>(
            value: currentFilter,
            items: FilterType.values.map((type) {
              return DropdownMenuItem(
                value: type,
                child: Text(_getFilterText(type)),
              );
            }).toList(),
            onChanged: (newType) {
              if (newType != null) {
                ref.read(filterTypeProvider.notifier).state = newType;
              }
            },
          )
        ],
      ),
      body: ListView.builder(
        itemCount: filteredTasks.length,
        itemBuilder: (context, index) {
          final task = filteredTasks[index];
          final remainingDays = calculateRemainingDays(task.targetDate);
          // 复用你已实现的颜色逻辑
          final textColor = remainingDays >=15 ? Colors.green 
                          : remainingDays >0 ? Colors.orange 
                          : Colors.grey;

          return ListTile(
            title: Text(task.title, style: TextStyle(color: textColor)),
            subtitle: Text(remainingDays >0 ? "剩余$remainingDays天" : "已过期"),
          );
        },
      ),
    );
  }

  String _getFilterText(FilterType type) {
    switch(type) {
      case FilterType.all: return "全部";
      case FilterType.next: return "距截止≥15天";
      case FilterType.almostDone: return "距截止1-14天";
      case FilterType.done: return "已过期";
    }
  }
}

核心逻辑说明

  • 过滤逻辑通过Riverpod的依赖追踪自动更新,原始数据或过滤类型变化时,filteredDataProvider会自动重新计算并刷新UI
  • 完全复用你已有的日期差计算和颜色设置逻辑,无需额外修改原有业务代码
  • 过滤类型切换仅需修改filterTypeProvider的状态,Riverpod会自动联动更新列表数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 04:10:14