【问题标题】:Flutter call back to originating widget on back button颤振回调到后退按钮上的原始小部件
【发布时间】:2018-07-16 15:03:33
【问题描述】:

我有一个构建 ListView.builder 的 Future Builder,构建器 ListTiles 由另一个具有 ontap 功能的小部件构建。我已经弄清楚如何使用后退按钮在最终的小部件上运行某些东西,但无法弄清楚如何在后退按钮上的原始小部件上调用某些东西。例如,当用户单击后退按钮时,我需要刷新顶级数据,而不仅仅是已经工作的辅助小部件中的数据。

我希望这是有道理的,任何帮助都会很棒。

更新这是代码。我正在简化我所展示的内容,因为做一个简单的例子会失去上下文。下面你会看到我有一个 FutureBuilder,它返回一个 ListBuilder,它返回一个新的 ChatWidget。这是顶层,当我点击后退按钮时,这个 Future 需要刷新。然而,捕获回调的 onTap 在 ChatWidget 中。

new Expanded(
      child: new RefreshIndicator(
          child: new FutureBuilder<List<Map>>(
              future: chatlist,
              builder: (BuildContext context, AsyncSnapshot<List<Map>> snapshot) {
                switch (snapshot.connectionState) {
                  case ConnectionState.none: return new Text('Waiting to start');
                  case ConnectionState.waiting: return new Text('Loading...');
                  default:
                    if (snapshot.hasError) {
                      return new Text('Error: ${snapshot.error}');
                    } else {
                      return new ListView.builder(
                        itemBuilder: (context, index) {
                          ChatServerList mychat = new ChatServerList(snapshot.data[index]['msgkey'],snapshot.data[index]['refid'],snapshot.data[index]['referralname'], snapshot.data[index]['oid'],snapshot.data[index]['sendname'],snapshot.data[index]['pid'],snapshot.data[index]['receivename'],snapshot.data[index]['pgrpid'],snapshot.data[index]['prid'],snapshot.data[index]['message'],);
                          bool isgroup = true;
                          if (mychat.grpid == 0) {
                            isgroup = false;
                          }
                          return new ChatWidget(mychat: mychat,threaded: threaded, isgroup: isgroup);
                        },
                        itemCount: snapshot.data.length,
                      );
                    }
                }
              },
          ),
          onRefresh: _onRefresh
      ),
  )

这是在 ChatWidget 中构建的,您会注意到 _onTap:

new MyListTile(
              leading: new CircleAvatar(
                child: _chatAvatar(),
                //child: !isgroup ? _indMsg() : _grpMsg(), radius: 18.0,
              ),
              //subtitle: new Text(widget.mychat.oname),
              title: new Text(widget.mychat.referralname),
              trailing: new Text(widget.mychat.oname, textAlign: TextAlign.right,),
              //isThreeLine: true,
              //onTap: doTap(threaded),
              onTap: _onTap,
              onLongPress: _doArchive,
            ),
            new MyListTile(
              leading: new Text('        '),
              title: new Text(submymessage, textAlign: TextAlign.left,
                style: new TextStyle(fontSize: 15.0,
                    color: Colors.grey, fontStyle: FontStyle.italic),),
              trailing: _unreadBabdge(),
              onTap: _onTap,
              onLongPress: _doArchive,
            ),

_onTap 在下面,并且有处理后退按钮的代码。

_onTap() async {
    ChatDB.instance.updateRead(widget.mychat.msgkey);
    if (threaded) {
      //TODO
    } else {
      Route route = new MaterialPageRoute(
        settings: new RouteSettings(name: "/ChatServerDivided"),
        builder: (BuildContext context) => new ChatServerDivided(mychat: widget.mychat, title: "Chat Messages",),
      );
      //Navigator.of(context).push(route);
      var nav = await Navigator.of(context).push(route);
      if(nav==true||nav==null){
        unread = ChatDB.instance.getUnread(widget.mychat.msgkey);
      }
    }


  }

所以我想要找到的是,如果这段代码可以以某种方式与原始小部件通信,以便我可以再次运行原始的 Future。我希望这更有意义,更容易理解。

【问题讨论】:

  • 没有例子这真的很混乱吗?
  • 添加了代码。这是您之前帮助我处理的同一页面,但现在我需要在同一背面刷新顶部的数据,并且不知道如何一直调用回原来的 Future。
  • 我并不是要发布完整的代码,我仍然对您的问题感到困惑。也许只是添加一个你想要实现的简化案例,一个关于虚拟数据的较小实验,以便任何人都可以轻松地遵循。
  • 如果您查看此项目,您帮助我处理了 stackoverflow.com/questions/48582963/… 它适用于具有路由的小部件(我的代码中的 ChatServerList),但是我需要顶层也刷新我的代码是 ChatServerPage 小部件。不知道如何让顶级小部件在同一个后退按钮单击时刷新
  • 您能否自定义链接中的示例以显示您的意思?对我来说让它更简单,因为浏览整个代码会很麻烦。只需创建一个虚拟示例来复制您的问题,以便我可以跟进。

标签: flutter


【解决方案1】:

是的,您可以这样做。无法确切看到将其放入您的代码的确切位置,但我会为您提供处理此问题的方法。导航器调用都是期货,这意味着您可以在调用方等待它们。似乎您只是缺少将值传递给 .pop 调用。下面是一个例子。

您可以在哪里导航,等待结果

var navigationResult = await Navigator.push(
        context,
        new MaterialPageRoute(
            builder: (context) => Page2()));

然后你可以用一个简单的if来检查navigationResult。

if(navigationResult == 'rerun_future') {
    uploadFiles(); // Perform your custom functionality here.
 }

您将这些信息传回的方式是,当您执行 pop 调用(导航返回)时,您将在其中传递值 'rerun_future'。

Navigator.of(context).pop('rerun_future') 

此外,如果您还想将此功能添加到后退按钮,您应该使用 WillPopScope 围绕您的 Scaffold,返回 false 给 onWillPop 并为您执行自定义弹出调用的 appBar 提供一个前导项。以下示例来自this post

@override
Widget build(BuildContext context) {
  return new WillPopScope(
    onWillPop: () async => false,
    child: new Scaffold(
      appBar: new AppBar(
        title: new Text("data"),
        leading: new IconButton(
          icon: new Icon(Icons.ac_unit),
          onPressed: () => Navigator.of(context).pop('rerun_future'), //<----- pass value here too
        ),
      ),
    ),
  );
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-27
    • 2021-06-10
    • 1970-01-01
    • 2021-02-19
    • 2021-03-22
    • 2022-08-19
    • 1970-01-01
    • 2022-09-26
    相关资源
    最近更新 更多