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

Flutter中如何手动触发SearchAnchor的suggestionsBuilder重建?

解决SearchAnchor的suggestionsBuilder无法随外部状态重建的问题

问题核心在于:SearchAnchor.bar的suggestionsBuilder回调仅会在SearchController的文本内容变化时被调用,外部状态(比如你的Riverpod计数器)更新并不会触发这个回调重新执行。你之前直接在suggestionsBuilder里调用ref.watch,只会在回调首次执行时获取一次状态值,后续状态变化无法触发UI更新。

解决方案:将状态监听逻辑移到suggestion子组件内部

把需要监听外部状态的部分用Consumer包裹,让子组件自身监听状态变化并重建,而不是依赖suggestionsBuilder的重新调用。

修改你的示例代码中SearchAnchor部分:

SearchAnchor.bar(
  suggestionsBuilder: (context, controller) {
    return [
      Consumer(
        builder: (context, ref, _) {
          int seconds = ref.watch(secondsCounterProvider);
          return Text(seconds.toString());
        },
      ),
    ];
  },
)

扩展到勾选框场景

如果要实现带勾选框的效果,同样把勾选状态(比如bool isChecked)放到状态管理中(比如Riverpod Provider),然后在suggestion的子组件里用Consumer监听这个状态,就能实时更新勾选状态:

SearchAnchor.bar(
  suggestionsBuilder: (context, controller) {
    return [
      Consumer(
        builder: (context, ref, _) {
          final isChecked = ref.watch(itemCheckedProvider);
          return ListTile(
            leading: Checkbox(
              value: isChecked,
              onChanged: (value) {
                ref.read(itemCheckedProvider.notifier).state = value!;
              },
            ),
            title: Text("选项"),
          );
        },
      ),
    ];
  },
)

额外优化:避免重复创建Timer

你的示例中callFunctionEverySecond会在seconds == 0时重复创建Timer,建议把Timer的管理移到Riverpod Notifier内部,避免内存泄漏:

@riverpod
class SecondsCounter extends _$SecondsCounter {
  Timer? _timer;

  @override
  int build() => 0;

  void startTimer() {
    _timer?.cancel();
    _timer = Timer.periodic(const Duration(seconds: 1), (timer) {
      log('increment Secondscounter');
      incrementSeconds();
    });
  }

  void incrementSeconds() => state++;

  @override
  void dispose() {
    _timer?.cancel();
    super.dispose();
  }
}

然后在build方法中启动Timer:

@override
Widget build(BuildContext context, WidgetRef ref) {
  int seconds = ref.watch(secondsCounterProvider);
  // 仅在首次构建时启动Timer
  ref.listenOnce(secondsCounterProvider, (previous, next) {
    ref.read(secondsCounterProvider.notifier).startTimer();
  });

  return Scaffold(
    // ... 其他代码
  );
}

内容的提问来源于stack exchange,提问作者Luca Köster

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 08:23:37