RefreshableComputedStateWrapper
A ComputedStateWrapper wrapped in a RefreshIndicator. It takes a RefreshableComputedState and wires pull-to-refresh to its refresh(), while rendering the same loading / failure / ready builders.
class ProfileView extends HookWidget {
const ProfileView({super.key, required this.service});
final ProfileService service;
Widget build(BuildContext context) {
// useAutoComputedState returns a MutableComputedState, which is a RefreshableComputedState.
final profileState = useAutoComputedState(service.load);
return RefreshableComputedStateWrapper<Profile>(
state: profileState,
inProgressBuilder: (context) => const Center(child: CircularProgressIndicator()),
failedBuilder: (context) => const Center(child: Text('Could not load the profile')),
// Swiping down calls state.refresh(); the content must be scrollable for the gesture.
builder: (context, profile) => ListView(children: [Text(profile.name)]),
);
}
}
Constructor
RefreshableComputedStateWrapper<E>({
Key? key,
required RefreshableComputedState<E> state,
required Widget Function(BuildContext) inProgressBuilder,
required Widget Function(BuildContext) failedBuilder,
required Widget Function(BuildContext, E) builder,
bool keepInProgress = false,
});
state- aRefreshableComputedState<E>, i.e. one that exposesrefresh(). TheMutableComputedStatereturned byuseComputedState/useAutoComputedStatequalifies.inProgressBuilder/failedBuilder/builder/keepInProgress- identical toComputedStateWrapper; see that page for the full semantics.
The only addition over ComputedStateWrapper is the surrounding RefreshIndicator: swiping down calls state.refresh(), swallowing a ComputedStateRefreshCancelled so the indicator settles cleanly if the refresh is superseded.
Use cases
- A single async value that the user should be able to pull to reload - a profile screen, a dashboard card - where you want explicit loading and error builders plus refresh, without wiring the
RefreshIndicatoryourself. - Combine with
keepInProgress: trueso the current value stays on screen during the pull-to-refresh, rather than collapsing to the loading builder mid-gesture.
For a collection that needs a distinct empty state alongside refresh, use RefreshableComputedIterableWrapper.
Caveats
-
buildermust return a scrollable.RefreshIndicatoronly arms the pull gesture when its child scrolls. A non-scrollingbuilderresult shows the value but can never be pulled - wrap it in aListViewor aSingleChildScrollViewwithAlwaysScrollableScrollPhysics. The loading and failure builders are already made scroll-fillable by the wrapper. -
statemust be aRefreshableComputedState, not a bareComputedState. A plain on-demandComputedStatehas norefresh()and won't type-check here; useComputedStateWrapperfor those. -
Everything from
ComputedStateWrappercarries over:buildernever gets null,failedBuildergets no error object, and anotInitializedstate renders as loading.
See also
- ComputedStateWrapper - the non-refreshable base, full builder semantics
- RefreshableComputedIterableWrapper - the collection variant with an empty builder
- useAutoComputedState - returns a
RefreshableComputedState, the usual source ofstate - useComputedState - the on-demand state and its
refresh()semantics