【问题标题】:How to Change AppBar 'title:' Value without Re-running FirebaseAnimatedList如何在不重新运行 FirebaseAnimatedList 的情况下更改 AppBar 'title:' 值
【发布时间】:2020-04-15 14:06:21
【问题描述】:

我在 Flutter/Dart 聊天应用程序中使用 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(),
            )
          ],
        ));
  }

我想根据侦听器返回的事件值更改第 5 行的_onLineStatus 的值,主要是为了指示其他聊天参与者是在线还是离线。我希望对状态的任何更改都能立即反映出来。显而易见的方法是使用 setState() ,但这当然会触发 build() 方法的完全重新运行,因此会重新运行 FirebaseAnimatedList 查询,再次下载相同的数据。我想避免这种情况。

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

因此我的问题是:

  1. 如何将对 FirebaseAnimatedList 的调用移到 build() 方法之外,以便我可以使用 setState() 来更新 AppBar title: property 的值,而无需重新运行 FirebaseAnimatedList?

或者...

  1. 如何在不重新运行 build() 方法的情况下更新 AppBar title: 属性的值,即。不调用 setState()?

【问题讨论】:

    标签: flutter firebase-realtime-database dart setstate


    【解决方案1】:

    创建一个包含您的应用栏的StateFullWidget。 像这样的:

    Widget build(BuildContext context) {
        return new Scaffold(
            appBar: CustomAppBar(), 
            body: Column(
            ...
    

    然后是您的新应用栏小部件:

    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),
        );
      }
    }
    

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

    【讨论】:

    • 感谢您的回答。说得通。我只能在明天试用,然后再回复您。
    • 抱歉回复慢。我不得不将我的监听器移动到新的小部件中,以便调用 setState() 来更改状态,这导致了很多其他问题,因为我也需要调用页面中的监听器。所以目前我有两个活跃的听众在做同样的事情。再次感谢。顺便说一句,您的代码返回了第二个应用栏,而不仅仅是应用栏标题,所以我在使用中对其进行了一些修改。
    • 拥有多个监听器不是问题。当它变得复杂时,我建议探索Provider lib。对状态管理非常有用。
    • 谢谢@jbarat。我的应用目前使用 scoped_model,考虑到 2020 年底将弃用 scoped_model,我将考虑在今年晚些时候用 Provider 替换它。
    猜你喜欢
    • 1970-01-01
    • 2021-01-10
    • 2021-04-06
    • 2014-06-10
    • 1970-01-01
    • 2023-01-15
    • 2014-05-28
    • 2015-03-24
    • 1970-01-01
    相关资源
    最近更新 更多