【问题标题】:Late Initialization error appears till images loading from firebase在从 Firebase 加载图像之前,会出现后期初始化错误
【发布时间】:2021-08-18 05:18:24
【问题描述】:

我正在开发一个从 Firebase 存储中获取图像到列表视图小部件的应用。从 Firebase 加载图像没有问题,但在从 firebase 加载图像之前出现错误,称为“LateInitializationError: Field 'imageFile' has not been initialized.”。有什么解决方案吗?

class GuidePage extends StatefulWidget {
  @override
  _GuidePageState createState() => _GuidePageState();
}

class _GuidePageState extends State<GuidePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Container(
          width: MediaQuery.of(context).size.width,
          height: MediaQuery.of(context).size.height,
          decoration: BoxDecoration(
            image: DecorationImage(
              image: AssetImage("images/b.png"),
              fit: BoxFit.fill,
            ),
          ),
          child: SafeArea(
            child: InteractiveViewer(
              child: Container(
                  margin: EdgeInsets.symmetric(vertical: 20.0),
                  child: ListView.builder(
                      itemCount: getIndex(),
                      itemBuilder: (context, index) {
                        return ImageGridItem(index + 1); //image return
                      })),
            ),
          ),
        ),
      ),
    );
  }

  getIndex() {
    if (isEnglish) {
      return 208;
    } else {
      return 259;
    }
  }
}

class ImageGridItem extends StatefulWidget {
  int index = 1;

  ImageGridItem(int i) {
    this.index = i;
  }

  @override
  _ImageGridItemState createState() => _ImageGridItemState();
}

class _ImageGridItemState extends State<ImageGridItem> {
  late Uint8List imageFile;

  Reference photosReference =
      FirebaseStorage.instance.ref().child(getNameChild1());

  getImage() {
    if (!imageData.containsKey(widget.index)) {
      photosReference
          .child(getNameChild2())
          .getData(2 * 1024 * 1024)
          .then((data) {
        this.setState(() {
          imageFile = data!;
        });
        imageData.putIfAbsent(widget.index, () {
          requestedIndexes.add(widget.index);
          

          return imageFile;
        });
      }).catchError((error) {
        print(error);
      });
    } else {
      imageFile = imageData[widget.index]!;
    }
  }

  @override
  void initState() {
    super.initState();
    if (!imageData.containsKey(widget.index)) {
      getImage();
    } else {
      this.setState(() {
        imageFile = imageData[widget.index]!;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    if (imageFile == null) {
      CircularProgressIndicator();
      return Text("Empty");
    } else {
      return Image.memory(
        imageFile,
        fit: BoxFit.cover,
      );
    }
  }

  String CreateFinalIndex(int index) {
    int index_length = widget.index.toString().length;
    String zero_number = "0" * ((3 - index_length));
    String Final_Index = (zero_number + widget.index.toString());
    return Final_Index;
  }

  
  static getNameChild1() {
    if (isEnglish) {
      return "Guide";
    } else {
      return "GuideS";
    }
  }

  String getNameChild2() {
    String Final_Index = CreateFinalIndex(widget.index);
    if (isEnglish) {
      return "eGr12TG ICT-$Final_Index.jpg";
    } else {
      return "sGr12TG ICT-$Final_Index.jpg";
    }
  }
}

【问题讨论】:

    标签: android firebase flutter dart runtime-error


    【解决方案1】:

    当给一个变量添加“延迟”时,你保证了哪个变量会被初始化,所以将它与 null 进行比较是没有意义的,因为它永远不会为 null。如果在未初始化的情况下将变量与“延迟”进行比较,则会发生异常。

    在您的情况下,最好的选择是使用 bool 变量来监控进度。

    class _ImageGridItemState extends State<ImageGridItem> {
      late Uint8List imageFile;
      bool isLoading = true;
    
      Reference photosReference =
          FirebaseStorage.instance.ref().child(getNameChild1());
    
      getImage() {
        if (!imageData.containsKey(widget.index)) {
          photosReference
              .child(getNameChild2())
              .getData(2 * 1024 * 1024)
              .then((data) {
            this.setState(() {
              imageFile = data!;
              isLoading = false;
            });
            imageData.putIfAbsent(widget.index, () {
              requestedIndexes.add(widget.index);
    
              return imageFile;
            });
          }).catchError((error) {
            print(error);
          });
        } else {
          imageFile = imageData[widget.index]!;
        }
      }
    
      @override
      void initState() {
        super.initState();
        if (!imageData.containsKey(widget.index)) {
          getImage();
        } else {
          this.setState(() {
            imageFile = imageData[widget.index]!;
          });
        }
      }
    
      @override
      Widget build(BuildContext context) {
        if (isLoading) {
          CircularProgressIndicator();
          return Text("Empty");
        } else {
          return Image.memory(
            imageFile,
            fit: BoxFit.cover,
          );
        }
      }
    
      String CreateFinalIndex(int index) {
        int index_length = widget.index.toString().length;
        String zero_number = "0" * ((3 - index_length));
        String Final_Index = (zero_number + widget.index.toString());
        return Final_Index;
      }
    
      static getNameChild1() {
        if (isEnglish) {
          return "Guide";
        } else {
          return "GuideS";
        }
      }
    
      String getNameChild2() {
        String Final_Index = CreateFinalIndex(widget.index);
        if (isEnglish) {
          return "eGr12TG ICT-$Final_Index.jpg";
        } else {
          return "sGr12TG ICT-$Final_Index.jpg";
        }
      }
    }
    

    【讨论】:

      【解决方案2】:

      在 Dart 中,所有非late 的变量都被初始化为null。如果一个变量是不可为空的,那么如果它曾经包含 null 将会是一个错误,所以这是一个编译时错误:

      int? myInt;  // initialized to null
      String myString;  // compile-time error
      

      late 略有不同。 late 字段没有被初始化为 null,而是未初始化。这意味着当您第一次尝试获取该变量时,它必须已手动初始化,否则您将获得LateInitializationError

      简而言之,您不能使用!= null 来测试late 变量是否已初始化。

      一些解决方案:

      1. 使您的字段可以为空
      Uint8List? data;
      
      @override
      Widget build(BuildContext context) {
        if (data == null) return LoadingWidget();
        final nonNullData = data!;
        // now use the data to return the image
      }
      
      1. 存储一个额外的布尔值,表示“变量是否已初始化”:
      late Uint8List data;
      var isInitialized = false;
      
      Future<void> loadData() async {
        data = await getImageFromNetwork();
        isInitialized = true;
      }
      
      @override
      Widget build(BuildContext context) {
        if (!isInitialized) return LoadingWidget();
        // now use the data to return the image
      }
      

      【讨论】:

        猜你喜欢
        • 2018-01-20
        • 1970-01-01
        • 2021-08-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多