Flutter Web 仅在托管时显示灰屏,在调试或发布模式下没有任何错误

问题描述 投票:0回答:1

我已经从我的 IDE 构建了一个在调试和发布模式下运行良好的 Flutter Web 应用程序。但是,托管后我在其中一个小部件中看到灰屏。

我知道这个问题已经被问过很多次了,通常它会缩小到在调试模式下运行并检查日志是否存在任何问题,例如父小部件、扩展、灵活等...

我根本没有看到任何错误或警告。

但是,如果我在托管模式下运行 F12,我会看到以下错误:

异常:找不到 APP_TYPE 变量。缺失条目需要非空回退

enter image description here

除此之外,在我的 IDE 构建的调试/发布模式下完全没有问题。

这是有问题的小部件(灰屏小部件)的颤动检查器 enter image description here

enter image description here

在此处复制有问题的小部件代码:

Expanded(
                      flex: 3,
                      child: Column(
                        children: [
                          Row(
                            mainAxisAlignment: MainAxisAlignment.center,
                            crossAxisAlignment: CrossAxisAlignment.center,
                            children: [
                              AnimatedPackageStatusButton(
                                index: 0,
                                selectedIndex: _selectedPackageStatusIndex,
                                onChange: (idx) =>
                                    selectPackageStatusAction(idx, context),
                                title: paymentStatusName[
                                        PaymentStatus.values[0]]!
                                    .translate(context),
                                // packageStatus: getPackageStatusByIndex(0),
                              ),
                              context.getResponsiveValue(12).hSpace,
                              AnimatedPackageStatusButton(
                                index: 1,
                                selectedIndex: _selectedPackageStatusIndex,
                                onChange: (idx) =>
                                    selectPackageStatusAction(idx, context),
                                title: paymentStatusName[
                                        PaymentStatus.values[1]]!
                                    .translate(context),
                                // packageStatus: getPackageStatusByIndex(1),
                              ),
                            ],
                          ),
                          context.getResponsiveValue(16).vSpace,
                          Expanded(
                            child: Container(
                              clipBehavior: Clip.antiAlias,
                              decoration: BoxDecoration(
                                color: context.colorsTheme.tabBar,
                                borderRadius: BorderRadius.only(
                                  topLeft: context
                                      .getResponsiveValue(16)
                                      .cRadius,
                                  topRight: context
                                      .getResponsiveValue(16)
                                      .cRadius,
                                ),
                              ),
                              child: Column(
                                children: [
                                  PackagesListWidget(
                                    editPackageAction: (Package package) =>
                                        showEditPackageCostModal(package),
                                    packagesList: tabPackagesList,
                                    isItemDisabled: true,
                                    onChecked: (newValue, package) {
                                      int idx =
                                          tabPackagesList.indexOf(package);
                                      setState(
                                        () {
                                          tabPackagesList.removeAt(idx);
                                          tabPackagesList.insert(
                                            idx,
                                            package.copyWith(
                                                isChecked: newValue),
                                          );
                                        },
                                      );
                                    },
                                  ),
                                  AnimatedSwitcher(
                                    duration:
                                        const Duration(milliseconds: 300),
                                    child: tabPackagesList.isNotEmpty
                                        ? StoreBillingPackagesListFooterActions(
                                            packagesList: tabPackagesList
                                                .where((p) => p.isChecked)
                                                .toList(),
                                            showPrint:
                                                _selectedPackageStatusIndex ==
                                                    0,
                                            updateFunc: () => {
                                                  setState(() {
                                                    updateTabPackages(
                                                        context);
                                                  })
                                                })
                                        : const SizedBox.shrink(),
                                  ),
                                ],
                              ),
                            ),
                          ),
                        ],
                      ),
                    ),

上面使用的 2 个小部件是。 1 包列表小部件

Expanded(
  child: widget.packagesList.isEmpty
      ? EmptyListContainer(
          title: 'noPackagesFoundMessage'.translate(context),
        )
      : ListView.separated(
          padding: EdgeInsets.symmetric(
            vertical: context.responsiveValue(
              mobile: context.getResponsiveValue(20),
              largeTablet: 0,
            ),
          ),
          itemCount: widget.packagesList.length,
          itemBuilder: (BuildContext context, int index) {
            return PackageListItem(
              package: widget.packagesList[index],
              selectPackageAction: widget.selectPackageAction,
              isSelected:
                  widget.selectedPackage == widget.packagesList[index],
              isDisabled: widget.isItemDisabled,
              onChecked: widget.onChecked,
              editPackageAction: // todo: this condition should not be inside the package list in this case you can not use the edit in the future for such status
                  widget.packagesList[index].paymentStatus !=
                          PaymentStatus.paid
                      ? widget.editPackageAction
                      : null,
            );
          },
          separatorBuilder: (BuildContext context, int index) {
            return context.responsiveValue(
              mobile: context.getResponsiveValue(12).vSpace,
              largeTablet: Divider(
                color: context.colorsTheme.background,
              ),
            );
          },
        ),
);

和页脚:

BlocListener<PackagesBloc, PackagesState>(
  listener: (context, state) {
    if (state.status == PackagesStatus.loading) {
      log('loading packages');
      context.read<GlobalLoadingBloc>().add(GlobalStartLoading());
    } else if (state.status == PackagesStatus.failed) {
      log('loading packages');
      context.read<GlobalLoadingBloc>().add(GlobalEndLoading());
      showFlashMessage(
        flashType: FlashType.error,
        bodyText: state.message.translate(context),
      );
    } else {
      context.read<GlobalLoadingBloc>().add(GlobalEndLoading());
      updateFunc();
      showFlashMessage(
        flashType: FlashType.success,
        bodyText: "packagesMarkedAsPaidMsg".translate(context),
      );
    }
  },
  child: Container(
    padding: EdgeInsets.symmetric(
      horizontal: context.getResponsiveValue(16),
      vertical: context.getResponsiveValue(16),
    ),
    decoration: BoxDecoration(
      color: context.colorsTheme.secondary,
      borderRadius: BorderRadius.only(
        topLeft: Radius.circular(
          context.getResponsiveValue(16),
        ),
        topRight: Radius.circular(
          context.getResponsiveValue(16),
        ),
      ),
    ),
    child: Row(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      children: [
        Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Row(
              children: [
                Text(
                  "${'totalSelectedPackages'.translate(context)}: ",
                  style: context.textTheme.normalMedium.copyWith(
                    color: context.colorsTheme.onSecondary,
                  ),
                ),
                context.getResponsiveValue(8).hSpace,
                Text(
                  packagesList.length.toString(),
                  style: context.textTheme.boldMedium.copyWith(
                    color: context.colorsTheme.onSecondary,
                  ),
                ),
              ],
            ),
            Row(
              children: [
                Text(
                  "${'totalToPay'.translate(context)}: ",
                  style: context.textTheme.normalMedium.copyWith(
                    color: context.colorsTheme.onSecondary,
                  ),
                ),
                Text(
                  (packagesList.fold(
                      0.0,
                      (previousValue, element) =>
                          previousValue + element.cost)).toStringAsFixed(2),
                  style: context.textTheme.boldMedium.copyWith(
                    color: context.colorsTheme.onSecondary,
                  ),
                ),
              ],
            ),
          ],
        ),
        !showPrint || packagesList.isEmpty
            ? const SizedBox.shrink()
            : Link(
                text: 'markSelectedAsPaid'.translate(context),
                onTap: () {
                  showMarkPackageAsPaidModal(context);
                },
                textColor: context.colorsTheme.onSecondary,
              ),
        !showPrint || packagesList.isEmpty
            ? const SizedBox.shrink()
            : Link(
                text: 'printSelected'.translate(context),
                onTap: () {
                  context.push(
                    RoutePaths.packagePDFScreenRoute.path,
                    extra: {
                      "packagesList": packagesList,
                      "summary": true,
                      "pdfFor": "store",
                    },
                  );
                },
                textColor: context.colorsTheme.onSecondary,
              ),
      ],
    ),
  ),
);
flutter
1个回答
0
投票

查看您的小部件树,我可以看到其中一个

Expanded
小部件位于
Padding
小部件内。

PackageListItem -> Row -> Padding -> Expanded

这一定会导致

Invalid Parent data widget exception
产生“灰屏”问题。请参阅附图,指出问题所在的树的确切级别。

尝试将

Expanded
直接放在
Row
下方,然后将其包裹在
Padding

参考:https://docs.flutter.dev/testing/common-errors#in Correct-use-of-parentdata-widget[在此处输入图像描述]1

© www.soinside.com 2019 - 2024. All rights reserved.