I am using FirebaseAnimatedList in a Flutter/Dart chat app. The simplified build() method is as follows:
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(
title: Text(_onLineStatus), // <-- This text value changed using setState()
),
body: Column(
children: <Widget>[
Flexible(
child: FirebaseAnimatedList(
query: reference,
sort: (a, b) => b.key.compareTo(a.key),
padding: EdgeInsets.all(8.0),
reverse: true,
itemBuilder: (BuildContext context, DataSnapshot snapshot,
Animation<double> animation, int index) {
return ChatMessage(snapshot: snapshot, animation: animation);
},
),
),
Divider(height: 1.0),
Container(
decoration: BoxDecoration(color: Theme.of(context).cardColor),
child: _buildTextComposer(),
)
],
));
}
I want to change the value of _onLineStatus
on line 5 based on an event value returned by a listener, basically to indicate if the other chat participant in on or off line. I want any change to the status to reflect immediately. The obvious way to do this is to use setState() but of course this triggers a full rerun of the build() method which therefore reruns the FirebaseAnimatedList query, downloading the same data once again. I want to avoid this.
All examples of the use of FirebaseAnimatedList show it as part of the build() method yet we are recommended to avoid putting database calls into build() to avoid these side-effects, because build() can be run multiple times.
My questions therefore are:
OR...
Create a StateFullWidget
containing your app bar.
Something like this:
Widget build(BuildContext context) {
return new Scaffold(
appBar: CustomAppBar(),
body: Column(
...
And then your new appbar widget:
class CustomAppBar extends StatefulWidget {
@override
_CustomAppBarState createState() => _CustomAppBarState();
}
class _CustomAppBarState extends State<CustomAppBar> {
String _onLineStatus = "online";
@override
Widget build(BuildContext context) {
return AppBar(
title: Text(_onLineStatus),
);
}
}
in this way you can independently rebuild the appbar from the list. You need to call setState
in your new widget.