如何在构建小部件中使用导航器进行重定向

Posted

技术标签:

【中文标题】如何在构建小部件中使用导航器进行重定向【英文标题】:How to use Navigator in Build Widget for Redirect 【发布时间】:2021-02-05 20:59:17 【问题描述】:

我有一个屏幕 (ProductAddScreen.dart) 尝试从 firestore 加载数据(产品未发布),但如果列表为空,我想重定向到新屏幕 (ProductFormScreen.dart)。

  @override
  Widget build(BuildContext context) 
    return StreamBuilder<List<Product>>(
      stream: context.watch<ProductService>().unpublished(),
      initialData: [],
      builder: (context, snapshot) 
        if (snapshot.connectionState == ConnectionState.waiting) 
          return Loading(color: Colors.green);
        

        // ════════ Exception caught by widgets library ════════
        // setState() or markNeedsBuild() called during build.

        if (!snapshot.hasData) 
          Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => ProductFormScreen()));
        

        return Scaffold(
          appBar: AppBar(
            title: Text(Strings.productAddAppBarTitle),
          ),
          body: ListView.separated(
            itemBuilder: (context, index) 
              final product = snapshot.data[index];
              return ProductItemRow(
                product: snapshot.data[index],
                onTap: () => print('hello'),
              );
            ,
            separatorBuilder: (context, index) => Divider(height: 0),
            itemCount: snapshot.data.length,
          ),
        );
      ,
    );
  

我来自 react js,我想我很困惑。如何使用 Flutter 做到这一点?

【问题讨论】:

【参考方案1】:

由于错误状态,您尝试在构建期间导航;

为避免这种情况,可以使用构建后回调:

WidgetsBinding.instance.addPostFrameCallback((_) 
    Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => ProductFormScreen()));
);

【讨论】:

我刚刚测试过,它按预期工作。我觉得这有点像 hack .. 我可以改进我的代码以更好地处理这个问题吗? 可以做类似的事情:***.com/questions/54101589/…【参考方案2】:
if(snapshot.hasData)
   if(snapshot.data.yourList.length == 0)
       Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => 
       ProductFormScreen()));
   
   return Scaffold(
       //your design
   );

注意:- 在您的模型中初始化您的列表,如

List<YourListObject> list = [];

【讨论】:

【参考方案3】:
Future navigateToSubPage(context) async 
  Navigator.push(context, MaterialPageRoute(builder: (context) => SubPage()));

检查列表是否为空的示例代码

return _items.isEmpty ? Center(child: Text('Empty')) : ListView.builder(
  itemCount: _items.length,
  itemBuilder: (context, index) 
    return _buildFilteredItem(context, index);
  ,
)
    

【讨论】:

以上是关于如何在构建小部件中使用导航器进行重定向的主要内容,如果未能解决你的问题,请参考以下文章

如何将父小部件焦点重定向到子小部件?

如何将“stdout”重定向到标签小部件?

将标准输出从多处理重定向到 Tkinter 文本小部件

如何将标准输出重定向到 Tkinter Text 小部件

html ActionKit小部件重定向

如何从Tkinter,Python中的Text小部件中移除焦点