Skip to content

Instantly share code, notes, and snippets.

@aloisdeniel
Last active April 17, 2021 20:14
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aloisdeniel/cfc6d4c0bac34757395b6b02ca6e6c19 to your computer and use it in GitHub Desktop.
Save aloisdeniel/cfc6d4c0bac34757395b6b02ca6e6c19 to your computer and use it in GitHub Desktop.
This example shows how, in a majority of cases, Streams cause unnecessary rebuilds in initial state.
import 'package:flutter/material.dart';
import 'package:rxdart/rxdart.dart';
// Global application configuration and navigation
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) => MaterialApp(home: Home());
}
class Home extends StatelessWidget {
Widget _button(BuildContext context, String title, WidgetBuilder builder) => RaisedButton(
child: Text(title),
onPressed: () => Navigator.push(
context, MaterialPageRoute(builder: builder)));
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
_button(context, "Streams", (c) => StreamExample()),
_button(context, "Notifiers", (c) => NotifierExample()),
],
);
}
}
// Basic view that displays two properties
class ExampleView extends StatelessWidget {
final String title;
final String description;
ExampleView({@required String title, @required String description}) : this.title = title ?? "<EMPTY>", this.description = description ?? "<EMPTY>";
@override
Widget build(BuildContext context) {
print("ExampleView built with title:'$title' and description: '$description'");
return Scaffold(
appBar: AppBar(title: Text(this.title)),
body: Text(this.description),
);
}
}
// With Streams/RX
// ----
//
// Two initial rebuilds while we know we have values.
//
// I/flutter (31663): ExampleView built with title:'<EMPTY>' and description: '<EMPTY>'
// I/flutter (31663): ExampleView built with title:'Stream's example' and description: 'This shows how Streams with empty inital data cause more rebuild than ValueListenable.'
class StreamModel {
final title = BehaviorSubject.seeded("Stream's example");
final description = BehaviorSubject.seeded(
"This shows how Streams with empty inital data cause more rebuild than ValueListenable.");
Future<void> dispose() async {
Future.wait([
this.title.close(),
this.description.close(),
]);
}
}
class StreamExample extends StatefulWidget {
@override
_StreamExampleState createState() => _StreamExampleState();
}
class _StreamExampleState extends State<StreamExample> {
final model = StreamModel();
@override
void dispose() {
super.dispose();
model.dispose();
}
@override
Widget build(BuildContext context) {
return StreamBuilder(
stream: model.title,
builder: (context, title) {
return StreamBuilder(
stream: model.description,
builder: (context, description) {
return ExampleView(
title: title.data, description: description.data);
});
});
}
}
// With Notifiers/ValueListenable
// ----
//
// Only one build since ValueListenable always has a stored value.
//
// I/flutter (31663): ExampleView built with title:'Notifier's example' and description: 'This shows how Streams with empty inital data cause more rebuild than ValueListenable.'
class NotifierModel {
final title = ValueNotifier("Notifier's example");
final description = ValueNotifier(
"This shows how Streams with empty inital data cause more rebuild than ValueListenable.");
void dispose() async {
this.title.dispose();
this.description.dispose();
}
}
class NotifierExample extends StatefulWidget {
@override
_NotifierExampleState createState() => _NotifierExampleState();
}
class _NotifierExampleState extends State<NotifierExample> {
final model = NotifierModel();
@override
void dispose() {
super.dispose();
model.dispose();
}
@override
Widget build(BuildContext context) {
return ValueListenableBuilder(
valueListenable: model.title,
builder: (context, title, _) {
return ValueListenableBuilder(
valueListenable: model.description,
builder: (context, description, _) {
return ExampleView(
title: title, description: description);
});
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment