Flutter中的LateInitializationError在AlertDialogs中发生。

huangapple go评论66阅读模式
英文:

Flutter LateInitializationError in AlertDialogs

问题

I have used the below class for layout variables. And I have called the init() method inside the build function of my root widget where I have the MaterialApp.

我使用了以下类来布局变量。并且我在根部件的`build`函数中调用了`init()`方法,其中包括`MaterialApp`。
The above implementation works throughout the app but fails when used inside `alertDialog`.

```dart
上述实现在整个应用程序中都可以正常工作,但在`alertDialog`内部使用时会失败。
Calling the above function raises the following error:

```dart
调用上述函数会引发以下错误:

LateInitializationError: Field '_unitWidth@919436592' has not been initialized.
LateInitializationError:字段`_unitWidth@919436592`尚未初始化。
But the method was called before and all the variables have been initialized.
但该方法在之前已被调用,并且所有变量都已初始化。
英文:

I have used the below class for layout variables. And I have called the init() method inside the build function of my root widget where I have the MaterialApp.

class LayoutConstraints {
  static final LayoutConstraints _singleton = LayoutConstraints._internal();
  factory LayoutConstraints() => _singleton;
  LayoutConstraints._internal();

  MediaQueryData? _mediaQueryData;
  late double _width, _height, _unitHeight, _unitWidth;

  init(BuildContext context) async {
    _mediaQueryData = MediaQuery.of(context);
    _width = _mediaQueryData!.size.width;
    _height = _mediaQueryData!.size.height - 30;
    _unitWidth = _mediaQueryData!.size.width / 100;
    _unitHeight = _mediaQueryData!.size.height / 100;
  }

  MediaQueryData mediaQuery() => _mediaQueryData!;
  double percentHeight(double percent) => percent * _unitHeight;
  double percentWidth(double percent) => percent * _unitWidth;
}

The above implementation works throughout the app but fails when used inside alertDialog.

alertDialog(
  BuildContext context, {
  required String title,
  required String content,
  required String buttonName,
  required VoidCallback onPressed,
}) {
  return showDialog<bool>(
    context: context,
    barrierDismissible: false,
    builder: (BuildContext context) => AlertDialog(
      icon: const Icon(Icons.error_outline, size: 60),
      title: Text(title),
      content: SizedBox(
        width: LayoutConstraints().percentWidth(40.0),
        child: Text(content),
      ),
      actions: [
        TextButton(
          onPressed: onPressed,
          child: Text(
            buttonName,
          ),
        )
      ],
    ),
  );
}

Calling the above function raises the following error:

LateInitializationError: Field '_unitWidth@919436592' has not been initialized.

But the method was called before and all the variables have been initialized.

答案1

得分: 0

在分析我的代码后,我发现了我犯的错误。我已经将相同的上下文传递给了alertDialog函数,但在构建器(builder)中,我错误地初始化了一个新的上下文。一旦我将构建器方法从

builder: (BuildContext context){}

更改为

builder: (context){}

一切都正常工作。

@TheSylar 我理解单例模式的复杂性,但对于我的用例,LayoutConstraints类将仅在应用程序启动时初始化一次,并且将由整个应用程序中的许多小部件访问。因此,单例类在这里很适用。

英文:

After analyzing my code, I found out the mistake I did. I have passed the same context to the alertDialog function but in the builder, I have mistakenly initiated a new context. Once I changed the builder method from

> builder: (BuildContext context){} to builder: (context){}

everything works.

@TheSylar I understand the complexities in singleton pattern but for my use case, the LayoutConstraints class will be initiated only once at the app startup and will be accessed by many widgets throughout the app. So, a singleton class will work good here.

huangapple
  • 本文由 发表于 2023年6月12日 18:53:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/76455943.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定