Flutter - 从 AppBar 返回上一页不会刷新页面,使用 Navigator.pop(context)

Posted

技术标签:

【中文标题】Flutter - 从 AppBar 返回上一页不会刷新页面,使用 Navigator.pop(context)【英文标题】:Flutter - Returning to previous page from AppBar is not refreshing the page, with Navigator.pop(context) 【发布时间】:2020-09-25 19:33:59 【问题描述】:

如果方法在另一个页面上运行,我试图刷新列表页面。我确实使用推送导航传递上下文。

我尝试遵循Answer 1 Answer 2 和 Answer 3 这 3 个答案,但我无法在此处管理状态。

这是第一个需要刷新的列表页面。它调用一个类

class _PageLocalState extends State<PageLocal> 
  @override
  Widget build(BuildContext context) 
    return Container(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.start,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: <Widget>[
          Expanded(
            child: SafeArea(
                child: ListView.builder(
              scrollDirection: Axis.vertical,
              shrinkWrap: true,
              itemCount: widget.allLocal.length,
              //padding: const EdgeInsets.only(top: 10.0),
              itemBuilder: (context, index) 
                return LocalCard(widget.allLocal[index]);
              ,
            )),
          )
        ],
      ),
    );
  

下一节课:

class LocalCardState extends State<LocalCard> 
  FavData localdet;

  LocalCardState(this.localdet);

  ListTile makeListTile() => ListTile(
        contentPadding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 10.0),
        title: Text(
          localdet.name,
          style: TextStyle(fontWeight: FontWeight.bold),
        ),
        subtitle: Text(localdet.loc),
        trailing: Icon(Icons.keyboard_arrow_right, size: 30.0),
        onTap: () => navigateToDetail(localdet),
      );

  Widget get localCard 
    return new Card(
        elevation: 4.0,
        margin: new EdgeInsets.symmetric(horizontal: 10.0, vertical: 6.0),
        child: Container(
          child: makeListTile(),
        ));
  

  @override
  Widget build(BuildContext context) 
    return new Container(
      child: localCard,
    );
  

  navigateToDetail(FavData localdet) 
    Navigator.push(
        context,
        MaterialPageRoute(
            builder: (context) => FavouriteDetailPage(
                  mndet: localdet,
                )));
    setState(() );
  

现在这是路由到最终的详细信息页面:

class _FavouriteDetailPageState extends State<FavouriteDetailPage> 
  bool isFav = false;
  FavData mndet;
  _FavouriteDetailPageState(this.mndet);

  // reference to our single class that manages the database
  final dbHelper = DatabaseHelper.instance;

  @override
  Widget build(BuildContext context) 
    Widget heading = new Container(...);

    Widget middleSection = new Expanded(...);

    Widget bottomBanner = new Container(...);

    Widget body = new Column(...);

    final makeBottom = Container(
      height: 55.0,
      child: BottomAppBar(
        color: Color.fromRGBO(36, 36, 36, 1.0),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: <Widget>[
            new FavIconWidget(mndet),
          ],
        ),
      ),
    );

    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
        title: Text('The Details'),
        backgroundColor: Color.fromRGBO(36, 36, 36, 1.0),
      ),
      body: Container(
        child: Card(
          elevation: 5.0,
          shape: RoundedRectangleBorder(
            side: BorderSide(color: Colors.white70, width: 1),
            borderRadius: BorderRadius.circular(10),
          ),
          margin: EdgeInsets.all(20.0),
          child: Padding(
            padding: new EdgeInsets.symmetric(vertical: 16.0, horizontal: 16.0),
            child: body,
          ),
        ),
      ),
      bottomNavigationBar: makeBottom,
    );
  

  void share(BuildContext context, FavData mndet) 
    final RenderBox box = context.findRenderObject();
    final String shareText = "$mndet.name - $mndet.desc";
    Share.share(shareText,
        subject: mndet.loc,
        sharePositionOrigin: box.localToGlobal(Offset.zero) & box.size);
  


class FavIconWidget extends StatefulWidget 
  final FavData mnforIcon;
  FavIconWidget(this.mnforIcon);
  @override
  _FavIconWidgetState createState() => _FavIconWidgetState();


class _FavIconWidgetState extends State<FavIconWidget> 
  final dbHelper = DatabaseHelper.instance;

  Future<bool> get isFav async 
    final rowsPresent = await dbHelper.queryForFav(widget.mnforIcon.id);
    if (rowsPresent > 0) 
      print('Card Loaded - Its Favourite already');
      return false;
     else 
      print('Card Loaded - It is not favourite yet');
      return true;
    
  

  void _insert() async ...

  void _delete() async ...

  @override
  Widget build(BuildContext context) 
    return FutureBuilder<bool>(
        future: isFav,
        initialData:
            false, // you can define an initial value while the db returns the real value
        builder: (context, snapshot) 
          if (snapshot.hasError)
            return const Icon(Icons.error,
                color: Colors.red); //just in case the db return an error
          if (snapshot.hasData)
            return IconButton(
                icon: snapshot.data
                    ? const Icon(Icons.favorite_border, color: Colors.white)
                    : Icon(Icons.favorite, color: Colors.red),
                onPressed: () => setState(() 
                      if (!snapshot.data) 
                        print('Its favourite so deleting it.');
                        _delete();
                       else 
                        print('Wasnt fav in the first place so inserting.');
                        _insert();
                      
                    ));

          return CircularProgressIndicator(); //if there is no initial value and the future is not yet complete
        );
  

我确信这只是我所做的一些愚蠢的编码,但无法找出答案。在哪里。 我尝试添加 Navigator.pop(context);在详细信息页面的不同部分中,它失败了。

目前,我必须导航回收藏夹列表页面,然后返回主页,然后返回收藏夹列表页面以刷新列表。

【问题讨论】:

我不完全理解您的问题,不确定以下是否可行,但您可以尝试以下操作。当与 widget.allLocal[index] 创建 LocalCard 时,您还可以传递 setState 并将其作为 stateSetter 保存在有状态的小部件中。然后在 navigateToDetail 在 Navigator.push 之前添加一个 await ,然后调用您之前保存的 statesetter。 谢谢,我们会尝试并让您随时了解情况。问题基本上是,我从本地数据库中获取一些数据,然后将其用作列表构建器。从详细信息卡页面,用户可以收藏该卡。如果是,那么它将转到单独的收藏夹列表。当用户从详细信息卡中取消选中收藏夹按钮时,此处的列表不会刷新。希望这有点道理。 那么当您从详细信息页面返回时,您是否希望再次运行填充 widget.allLocal 中所有数据的函数? 是的,没错,但前提是满足条件。 我不完全确定这会奏效,所以你可以试试这个并告诉我。当与 widget.allLocal[index] 一起创建 LocalCard 时,您可以将类的实例作为 t​​his 传递,即“return LocalCard(widget.allLocal[index], this);”并将其作为变量保存在有状态小部件中,即“var mainpage = ...”。然后在 navigateToDetail 在 Navigator.push 之前添加一个等待,然后调用更新函数,例如“mainpage.FunctionThatUpdates()”。 【参考方案1】:

试试这个.. 任何你使用 Navigator.pop 或 Navigator.push .. 而不是这个使用这个:

      Navigator.pushReplacement(context,
        MaterialPageRoute(builder: (BuildContext context) => Password())
       );

        //instead of Password use the name of the page(the second page you want to go to)

【讨论】:

以上是关于Flutter - 从 AppBar 返回上一页不会刷新页面,使用 Navigator.pop(context)的主要内容,如果未能解决你的问题,请参考以下文章

Navigator.pop(context) 不返回上一屏 Flutter

Flutter:从 AppBar 中减去状态栏高度

Flutter webapp:Snapshort返回一个空值

Flutter:如何从 appbar 动作中显示快餐栏

如何在 Flutter 的 AppBar 中有可点击的文本

Flutter:从 appbar 调用 listview builder 中的方法