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

Flutter 3.16.0中CupertinoPicker内CustomPainter颜色不实时更新问题

解决CupertinoPicker中CustomPainter颜色不实时更新的问题

问题核心原因

CupertinoPicker.builder会缓存已构建的item,同时如果CustomPainter的shouldRepaint方法没有正确判断状态变化,就会出现颜色更新但界面不刷新的情况——只有关闭对话框重新打开,Picker才会重新构建所有item,显示正确颜色。

具体修复步骤

1. 让CustomPainter正确响应颜色变化

确保shouldRepaint方法在颜色(或其他关键绘制参数)变化时返回true,告诉Flutter需要重绘:

class DateRowPainter extends CustomPainter {
  final Color textColor;
  final String date;

  DateRowPainter({required this.textColor, required this.date});

  @override
  void paint(Canvas canvas, Size size) {
    // 示例绘制逻辑:使用textColor绘制日期文本
    final textPainter = TextPainter(
      text: TextSpan(text: date, style: TextStyle(color: textColor)),
      textDirection: TextDirection.ltr,
    )..layout(minWidth: size.width, maxWidth: size.width);
    textPainter.paint(canvas, Offset(0, (size.height - textPainter.height)/2));
  }

  @override
  bool shouldRepaint(DateRowPainter oldDelegate) {
    // 只要颜色或日期不一致,就触发重绘
    return oldDelegate.textColor != textColor || oldDelegate.date != date;
  }
}

2. 强制CupertinoPicker刷新item

给CupertinoPicker.builder绑定一个动态的key,当数据库查询结果变化时,更新这个key,让Picker重建所有item:

// 在State类中定义状态变量,标记查询状态变化
bool _entryStatusChanged = false;

// 数据库查询完成后更新状态
void _refreshDatabaseStatus() async {
  // 执行你的数据库查询逻辑
  // ...
  // 查询完成后触发状态更新
  setState(() {
    _entryStatusChanged = !_entryStatusChanged;
  });
}

// 构建CupertinoPicker
CupertinoPicker.builder(
  key: ValueKey(_entryStatusChanged), // 状态变化时触发Picker重建
  itemExtent: 40,
  itemBuilder: (context, index) {
    final targetDate = _dateList[index];
    final hasEntry = _checkDatabaseEntry(targetDate); // 你的数据库判断逻辑
    final textColor = hasEntry ? Colors.blue : Colors.red;
    return CustomPaint(
      painter: DateRowPainter(textColor: textColor, date: targetDate),
      size: const Size(double.infinity, 40),
    );
  },
  onSelectedItemChanged: (index) {
    // 选中回调逻辑
  },
)

3. 确保状态更新时机正确

如果数据库查询是异步操作,必须在查询结果返回后调用setState,让Flutter重新执行itemBuilder,生成带有最新颜色的CustomPainter实例。

关键注意点

  • 不要复用CustomPainter实例:每次itemBuilder执行时,都要根据当前的hasEntry状态创建新的DateRowPainter实例,不能把Painter缓存到State里反复使用。
  • 避免Picker的item缓存:通过动态key强制Picker重建item,是解决CupertinoPicker缓存问题的直接方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 09:43:15