Flutter回拨到后退按钮上的原始小部件

时间:2018-02-06 14:04:35

标签: flutter

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

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

更新以下是代码。我正在简化我所展示的内容,因为制作一个简单的例子将失去上下文。下面你看到我有一个FutureBuilder返回一个返回一个新ChatWidget的ListBuilder。这是最高级别,单击后退按钮时需要刷新此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。我希望这更有意义,也更容易理解。

1 个答案:

答案 0 :(得分:2)

是的,您可以这样做。无法确切看到将其放入代码中的位置,但我将为您提供处理方法。导航器调用都是“期货”,这意味着您可以在调用方等待它们。似乎您只是缺少将值传递给.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并在执行自定义pop调用的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
        ),
      ),
    ),
  );
}