Navigator.push 可以和 Flutter 三元一起使用吗

Posted

技术标签:

【中文标题】Navigator.push 可以和 Flutter 三元一起使用吗【英文标题】:Can Navigator.push be used in ternary with Flutter 【发布时间】:2022-01-16 01:18:23 【问题描述】:

我有一个页面,其应用栏有四个选项卡。在其中一个选项卡上,如果条件为真,我试图在构建方法中使用条件来显示具有特定内容的自定义滚动视图。如果条件为假,我希望用户被导航到一个全新的页面,该页面只有一个列表视图和它自己的不包含任何选项卡的应用栏。 Navigator.push 用作三元中的第二个条件会引发错误。我在下面的代码中的目标类似于 if file == null 在 Safe Area 小部件中显示内容,否则导航到 UploadItemsFormPage。我一直无法弄清楚如何解决这个挑战。我试图删除很多代码以减少阅读量,但如果有必要提供帮助,我可以提供更多代码。代码将被重构为不同的小部件,但我认为这会使问这个问题变得更加复杂,所以现在它都在一个类中。提前感谢您的帮助。

class ShoppingAdminPage extends StatefulWidget 
  const ShoppingAdminPage(Key? key) : super(key: key);

  @override
  State<ShoppingAdminPage> createState() => _ShoppingAdminPageState();


class _ShoppingAdminPageState extends State<ShoppingAdminPage> 
  final List<String> _tabs = <String>[
    TabNameString.upload,
    'Tab Two',
    'Tab Three',
    'Tab Four',
  ];

  TextEditingController descriptionController = TextEditingController();
  String productID = DateTime.now().microsecondsSinceEpoch.toString();
  TextEditingController priceController = TextEditingController();
  TextEditingController titleController = TextEditingController();
  bool isUploading = false;
  File? file;

  void clearImage() 
    setState(() 
      file = null;
    );
  

  @override
  Widget build(BuildContext context) 
    return AdaptiveLayoutScaffold(
      drawer: const SideSheet(),
      landscapeBodyWidget: Container(),
      portraitBodyWidget: BrandTabController(
        actions: const [
          BrandPopUpMenu(),
        ],
        numberOfTabs: _tabs.length,
        pageName: PageName.shoppingAdmin,
        tabBarView: TabBarView(children: [
          file == null
              ? SafeArea(
                  top: false,
                  bottom: false,
                  child: Builder(
                    builder: (BuildContext context) 
                      return CustomScrollView(
                        key: const PageStorageKey<String>(
                          TabNameString.upload,
                        ),
                        slivers: <Widget>[
                          SliverOverlapInjector(
                            handle:
                                NestedScrollView.sliverOverlapAbsorberHandleFor(
                              context,
                            ),
                          ),
                          SliverToBoxAdapter(
                            child: Column(
                              mainAxisAlignment: MainAxisAlignment.center,
                              children: <Widget>[
                                const SizedBox(
                                  height: 60.0,
                                ),
                                SvgPicture.asset(
                                  ImageUrlString.uploadItemSVG,
                                  height: 260.0,
                                ),
                                Padding(
                                  padding: const EdgeInsets.only(
                                    top: 20.0,
                                  ),
                                  child: ElevatedButton(
                                    onPressed: () 
                                      showDialog(
                                          context: context,
                                          builder: (context) 
                                            return BrandSimpleDialog(
                                              dialogTitle:
                                                  DialogString.itemImage,
                                              optionOneCallback: () async 
                                                Navigator.pop(context);
                                                XFile? pickedFile =
                                                    await ImagePicker()
                                                        .pickImage(
                                                  imageQuality: 85,
                                                  maxHeight: 675,
                                                  maxWidth: 960,
                                                  source: ImageSource.camera,
                                                );
                                                setState(() 
                                                  file = File(pickedFile!.path);
                                                );
                                              ,
                                              optionOneText: DialogString
                                                  .captureWithCamera,
                                              optionTwoCallback: () async 
                                                Navigator.pop(context);
                                                XFile? pickedFile =
                                                    await ImagePicker()
                                                        .pickImage(
                                                  imageQuality: 85,
                                                  source: ImageSource.gallery,
                                                );
                                                setState(() 
                                                  file = File(pickedFile!.path);
                                                );
                                              ,
                                              optionTwoText: DialogString
                                                  .selectFromGallery,
                                            );
                                          );
                                    ,
                                    child: Text(
                                      ButtonString.uploadNewItems.toUpperCase(),
                                    ),
                                  ),
                                ),
                              ],
                            ),
                          ),
                        ],
                      );
                    ,
                  ),
                )
              : UploadItemsFormPage(
                  contentImage: file as File,
                  descriptionController: descriptionController,
                  isUploading: isUploading,
                  onPressedClear: clearImage,
                  priceController: priceController,
                  titleController: titleController,
                ),
          Container(),
          Container(),
          Container(),
        ]),
        tabs: _tabs,
      ),
    );
  

【问题讨论】:

你使用 Navigator.pushNamed(context, AppRoutes.uploadimages);就像是? uploadimages 是上传图片页面的路由。 @Jigangsu 感谢您的回复。我是 Flutter 和编码的初学者,所以我没有想过甚至没有尝试过你的想法。当我早上醒来时,这将是我尝试的第一件事。如果我成功了,我会告诉你的。再次感谢。 Navigator.push( context, MaterialPageRoute(builder: (context) => Uploadimages()), );上传图片是一个全新的屏幕。 @吉钢苏。谢谢你的帮助。您是否介意将您的答案添加为正式答案,以便我接受。如果社区中的其他一些初学者有同样的困惑,他们应该能够看到你的答案。我从代码中删除了三元运算符,并按照您的建议将 Navigator.push 添加到对话框按钮的回调中,现在我有了我想要的 UI 的确切行为。三元运算符根本没有任何作用。如果没有您的指导,我永远不会解决这个问题。 你也可以使用三元运算符 (file == null )?(你通常使用 file ): Navigator.push( context, MaterialPageRoute(builder: (context) => Uploadimages()) , ); 【参考方案1】:

在任何情况下都可以使用三元运算符。假设在您的上述情况下 (任何真正的代码,例如 file ==null )?(如果 file 为 null ,做一些工作):Navigator.push( context, MaterialPageRoute(builder: (context) => Uploadimages()), ); (如果三元编码不正确,请更改工作)

【讨论】:

以上是关于Navigator.push 可以和 Flutter 三元一起使用吗的主要内容,如果未能解决你的问题,请参考以下文章

Navigator.push 没有动画 - Flutter

在 Flutter 中使用 Navigator.push() 时出现黑屏

Dart / Flutter:在没有上下文的页面之间导航(使用 Navigator)(所以没有 Navigator.push?)

无法按下具有 Navigator.push 功能的 Flutter Button (GestureDetector)

每次Navigator.push到下一页时都会调用的回调

InheritedWidget - 在 navigator.push 之后在 null 上调用 getter