我有一个动态接受未来列表和回调的页面,以获取未来列表以接收数据并能够在刷新时刷新它。简化版本如下所示:
class ListSearchPage<T> extends StatefulWidget {
final Future<List<T>> itemsFuture;
final ValueGetter<Future<List<T>>> getItemsFuture;
const ListSearchPage({Key key, this.getItemsFuture, this.itemsFuture})
: super(key: key);
@override
_ListSearchPageState createState() => _ListSearchPageState();
}
class _ListSearchPageState<T> extends State<ListSearchPage> {
Future<List<T>> itemsFuture;
TextEditingController _controller;
@override
void initState() {
itemsFuture = widget.itemsFuture;
_controller = TextEditingController();
super.initState();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
future:
itemsFuture != null ? itemsFuture : widget.getItemsFuture(),
builder: (context, snapshot) {
return RefreshIndicator(
onRefresh: () async {
setState(() {
itemsFuture = null;
_controller.text = '';
});
},
child: ...
);
});
}
}
所以第一次,页面加载时已经加载了未来。当用户刷新时,我将未来标记为 null,以便调用回调并且可以重新获取数据。
我现在正在尝试在flutter_hooks
整个应用程序中实现,并且我已将此小部件重构为如下所示(简化版本):
class ListSearchPage<T> extends HookWidget {
final Future<List<T>> itemsFuture;
final ValueGetter<Future<List<T>>> getItemsFuture;
const ListSearchPage({Key key, this.getItemsFuture, this.itemsFuture})
: super(key: key);
@override
Widget build(BuildContext context) {
final itemsFutureNotifier = useState(this.itemsFuture);
final TextEditingController _controller = useTextEditingController();
return FutureBuilder(
future:
itemsFutureNotifier.value != null ? itemsFutureNotifier.value : getItemsFuture(),
builder: (context, snapshot) {
return RefreshIndicator(
onRefresh: () async {
itemsFutureNotifier.value = null;
_controller.text = '';
},
child: ...
);
});
}
}
这第一次有效,但是之后该值继续分配给 null,因此值通知程序不会收到有关更改的通知。在这种情况下,如何像以前一样强制重建小部件?作为奖励,您是否看到了更好的解决方案?
提前致谢。
更新
这是itemsFuture
final future = useMemoized(() => repository.fetchData());
这是getItemsFuture
() => repository.fetchData()
它背后的想法是在打开搜索页面之前获取数据。在我的用例中有效。
我找到了解决问题的方法,但我不会将其发布为答案,因为我不相信它是干净的,我宁愿看看是否有人找到了正确的方法。
当前解决方案
@override
Widget build(BuildContext context) {
// feels like a dirty solution for rebuilding on refresh
final counterNotifier = useState(0);
final itemsFutureNotifier = useState(this.itemsFuture);
final TextEditingController _controller = useTextEditingController();
return ValueListenableBuilder(
valueListenable: counterNotifier,
builder: (context, value, child) {
return FutureBuilder(
future:
itemsFutureNotifier.value != null ? itemsFutureNotifier.value : getItemsFuture(),
builder: (context, snapshot) {
return RefreshIndicator(
onRefresh: () async {
counterNotifier.value++;
itemsFutureNotifier.value = null;
_controller.text = '';
},
child: ...
);
});
});
如您所见,我现在有一个计数器通知器,它将实际重建ValueListenableBuilder
并FutureBuilder
获取数据