Flutter 如何更改AppBar';标题:';值,而不重新运行FirebaseAnimatedList

Flutter 如何更改AppBar';标题:';值,而不重新运行FirebaseAnimatedList,flutter,firebase-realtime-database,dart,setstate,Flutter,Firebase Realtime Database,Dart,Setstate,我正在一个颤振/飞镖聊天应用程序中使用FirebaseAnimatedList。简化的build()方法如下所示: @override Widget build(BuildContext context) { return new Scaffold( appBar: AppBar( title: Text(_onLineStatus), // <-- This text value changed using setState()

我正在一个颤振/飞镖聊天应用程序中使用FirebaseAnimatedList。简化的build()方法如下所示:

@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(),
            )
          ],
        ));
  }
@覆盖
小部件构建(构建上下文){
归还新脚手架(
appBar:appBar(
标题:Text(_onLineStatus),//b.key.compareTo(a.key),
填充:边缘设置。全部(8.0),
相反:是的,
itemBuilder:(BuildContext上下文、DataSnapshot快照、,
动画(整数索引){
返回消息(快照:快照,动画:动画);
},
),
),
分隔器(高度:1.0),
容器(
装饰:盒子装饰(颜色:主题.of(上下文).cardColor),
子项:_buildTextComposer(),
)
],
));
}
我想根据侦听器返回的事件值更改第5行的
\u onLineStatus
值,基本上是为了指示其他聊天参与者是在线还是离线。我希望状态的任何变化都能立即反映出来。显而易见的方法是使用setState(),但这当然会触发build()方法的完全重新运行,从而重新运行FirebaseAnimatedList查询,再次下载相同的数据。我想避免这种情况

所有使用FirebaseAnimatedList的示例都将其显示为build()方法的一部分,但我们建议避免将数据库调用放入build()以避免这些副作用,因为build()可以多次运行

因此,我的问题是:

  • 如何将对FirebaseAnimatedList的调用移到build()方法之外,以便在不重新运行FirebaseAnimatedList的情况下使用setState()更新AppBar title:属性的值 或者

  • 如何更新AppBar title:property的值而不重新运行build()方法,即不调用setState()

  • 创建一个包含应用程序栏的
    StateFullWidget
    。 大概是这样的:

    Widget build(BuildContext context) {
        return new Scaffold(
            appBar: CustomAppBar(), 
            body: Column(
            ...
    
    然后是新的appbar小部件:

    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),
        );
      }
    }
    
    类CustomAppBar扩展StatefulWidget{
    @凌驾
    _CustomAppBarState createState()=>\u CustomAppBarState();
    }
    类_CustomAppBarState扩展状态{
    字符串_onLineStatus=“online”;
    @凌驾
    小部件构建(构建上下文){
    返回AppBar(
    标题:文本(_onLineStatus),
    );
    }
    }
    

    通过这种方式,您可以从列表中独立重建appbar。您需要在新的小部件中调用
    setState

    谢谢您的回答。有道理。我明天只能尝试一下,到时候再给你回复。很抱歉回复太慢。为了调用setState()来更改状态,我不得不将我的侦听器移动到新的小部件中,这导致了许多其他问题,因为我也需要在调用页面中使用侦听器。所以现在我有两个积极的听众在做同样的事情。再次感谢。顺便说一句,您的代码会返回第二个应用程序条,而不仅仅是应用程序条标题,因此我在使用中对其进行了一些修改。有多个侦听器不是问题。当它变得复杂时,我建议探索
    提供程序
    库。对状态管理非常有用。谢谢@jbarat。我的应用程序目前使用的是scoped_模型,鉴于scoped_模型在2020年底被弃用,我将在今年晚些时候考虑用Provider替换它。