我想使用SearchAnchor Widget,但不幸的是,我找不到触发重建的方法。我尝试了很多方法来实现类似于我的图片suggestionBuilder中的清单中所示的效果。但是,它不起作用,因为只有当我输入新文本并且触发搜索控制器时,小部件才会重建。
我尝试使用有状态小部件并更改状态,但它不起作用。我还尝试了 ValueListenableBuilder 并尝试手动编辑 SearchController,这绝对不是有效的解决方案,也不起作用。我什至尝试了 Riverpod Provider,如提供的最小代码片段所示。
这让我发疯。感谢您的任何帮助! :D
使用 Riverpod 进行重现的最小示例(我使用的是 Flutter 3.16.3):
import 'dart:async';
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
part 'init_jobs_screen.g.dart';
class InitJobsScreen extends ConsumerWidget {
const InitJobsScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
//This value i want to display
int seconds = ref.watch(secondsCounterProvider);
final SecondsCounter notifier = ref.watch(secondsCounterProvider.notifier);
if (seconds == 0) {
callFunctionEverySecond(notifier);
}
return Scaffold(
appBar: AppBar(
title: const Text('Whats going on here?!'),
),
body: Column(
children: [
Text('Here it works as expected $seconds'),
//Here the provider doesnt work -> It drives me quazy
SearchAnchor.bar(
suggestionsBuilder: (context, controller) =>
[Text(ref.watch(secondsCounterProvider).toString())]),
],
));
}
}
//Provider i want to watch
@riverpod
class SecondsCounter extends _$SecondsCounter {
@override
int build() => 0;
void incrementSeconds() => state++;
}
//increment seconds
void callFunctionEverySecond(SecondsCounter notifier) {
// Call the function every second
Timer.periodic(const Duration(seconds: 1), (timer) {
log('increment Secondscounter');
notifier.incrementSeconds();
});
}
我尝试了有状态小部件并更改了状态,但这不起作用,我尝试了 ValueListenableBuilder,我尝试手动编辑 SearchController (这确实不是有效的解决方案,尽管不起作用),我尝试了 Riverpod Provider,就像提供的最小代码片段
如果您转到源文件 search_anchor.dart,在第 765 行左右,找到
didChangeDependencies()
函数,您将看到 suggestBuilder 是如何触发的:
@override
void didChangeDependencies() {
super.didChangeDependencies();
final Size updatedScreenSize = MediaQuery.of(context).size;
if (_screenSize != updatedScreenSize) {
_screenSize = updatedScreenSize;
if (widget.showFullScreenView) {
_viewRect = Offset.zero & _screenSize!;
}
}
if (searchValue != _controller.text) {
_timer?.cancel();
_timer = Timer(Duration.zero, () async {
searchValue = _controller.text;
result = await widget.suggestionsBuilder(context, _controller);
_timer?.cancel();
_timer = null;
});
}
}
注意线条:
if (searchValue != _controller.text){
...
result = await widget.suggestionsBuilder(context, _controller);
...
}
所以改变文本确实是触发 suggestBuilder 的唯一条件。因此,在 Flutter 团队添加诸如 buildWhen 参数之类的内容之前,最好的选择是完全绕过它或重置文本。
每当我需要重建时我都会这样做。不是最漂亮的解决方案,并且会导致刷新,但却是解决问题的最快答案。
SearchController searchController = SearchController();
...
SearchAnchor(
searchController: searchController,
...
);
...
final query = searchController.text;
searchController.text = '';
searchController.text = query;