在从 firebase 加载图像之前出现延迟初始化错误
Late Initialization error appears till images loading from firebase
我正在开发一个从 Firebase 存储中获取图像到列表视图小部件的应用程序。图片是从 Firebase 加载的,没有问题,但是在从 firebase 加载图片之前出现错误,称为“LateInitializationError:字段 'imageFile' 尚未初始化。”。对此有任何解决方案吗?
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";
}
}
}
将“late”添加到变量时,您保证将初始化哪个变量,因此将它与 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";
}
}
}
在 Dart 中,所有非 late
的变量都被初始化为 null
。如果一个变量是不可为空的,那么如果它曾经包含 null 就会出错,所以这是一个编译时错误:
int? myInt; // initialized to null
String myString; // compile-time error
但 late
略有不同。 late
字段没有初始化为 null,而是 未初始化 。这意味着您第一次尝试获取该变量时,它 必须 已被手动初始化,否则您将得到一个 LateInitializationError
.
简而言之,您不能使用!= null
来测试一个late
变量是否已经被初始化。
一些解决方案:
- 使您的字段可为空
Uint8List? data;
@override
Widget build(BuildContext context) {
if (data == null) return LoadingWidget();
final nonNullData = data!;
// now use the data to return the image
}
- 存储一个额外的布尔值,表示“变量是否已初始化”:
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
}
在将变量初始化为某物或 null 后为我工作,然后等待初始化:
例子
1. List _items = [];
2. this._items = await itemsDatabase.instance.readAllItems();
“在 initState 中”
当应用程序运行时,_items 会初始化一些空值,一段时间后实际值将替换空值。
我正在开发一个从 Firebase 存储中获取图像到列表视图小部件的应用程序。图片是从 Firebase 加载的,没有问题,但是在从 firebase 加载图片之前出现错误,称为“LateInitializationError:字段 'imageFile' 尚未初始化。”。对此有任何解决方案吗?
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";
}
}
}
将“late”添加到变量时,您保证将初始化哪个变量,因此将它与 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";
}
}
}
在 Dart 中,所有非 late
的变量都被初始化为 null
。如果一个变量是不可为空的,那么如果它曾经包含 null 就会出错,所以这是一个编译时错误:
int? myInt; // initialized to null
String myString; // compile-time error
但 late
略有不同。 late
字段没有初始化为 null,而是 未初始化 。这意味着您第一次尝试获取该变量时,它 必须 已被手动初始化,否则您将得到一个 LateInitializationError
.
简而言之,您不能使用!= null
来测试一个late
变量是否已经被初始化。
一些解决方案:
- 使您的字段可为空
Uint8List? data;
@override
Widget build(BuildContext context) {
if (data == null) return LoadingWidget();
final nonNullData = data!;
// now use the data to return the image
}
- 存储一个额外的布尔值,表示“变量是否已初始化”:
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
}
在将变量初始化为某物或 null 后为我工作,然后等待初始化:
例子
1. List _items = [];
2. this._items = await itemsDatabase.instance.readAllItems();
“在 initState 中”
当应用程序运行时,_items 会初始化一些空值,一段时间后实际值将替换空值。