Skip to content

Instantly share code, notes, and snippets.

@mirkancal
Last active October 31, 2022 07:02
Show Gist options
  • Save mirkancal/7b63c3794caf80f365f57469af054098 to your computer and use it in GitHub Desktop.
Save mirkancal/7b63c3794caf80f365f57469af054098 to your computer and use it in GitHub Desktop.
Flutter widget that refreshes itself periodically.
import 'package:flutter/material.dart';
typedef RefreshableWidgetBuilder<T> = Widget Function(
BuildContext context, T value);
typedef RefreshCall<T> = Future<T> Function();
class RefreshableBuilder<T> extends StatefulWidget {
RefreshableBuilder({
super.key,
required this.builder,
required this.refreshCall,
this.initialValue,
Duration? refreshRate,
}) : refreshRate = refreshRate ?? Duration(seconds: 20);
final RefreshableWidgetBuilder<T> builder;
final RefreshCall<T> refreshCall;
final Duration refreshRate;
final T? initialValue;
@override
State<RefreshableBuilder<T>> createState() => _RefreshableBuilderState<T>();
}
class _RefreshableBuilderState<T> extends State<RefreshableBuilder<T>> {
T? initialValue;
late Stream<T> stream;
T? cached;
@override
void initState() {
if (widget.initialValue != null) {
initialValue = widget.initialValue!;
}
stream = Stream.periodic(widget.refreshRate).asyncMap((_) async {
try {
final data = await widget.refreshCall();
cached = data;
return data;
} catch (e) {
if (cached != null) {
return cached!;
}
rethrow;
}
});
super.initState();
}
@override
Widget build(BuildContext context) {
return StreamBuilder<T>(
initialData: initialValue,
stream: stream,
builder: (BuildContext context, AsyncSnapshot<T> snapshot) {
if (snapshot.hasData) {
return widget.builder(context, snapshot.data!);
} else {
return Center(
child: CircularProgressIndicator(),
);
}
},
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment