Я пытаюсь получить список из API, который состоит из двух методов fetchImages и fetchCategories. в первый раз он показывает ошибку красного экрана, а затем через 2 секунды автоматически загружает список. Не могли бы вы рассказать мне, в чем проблема с моим кодом и как избежать отображения этой ошибки красного экрана в моем приложении?
Widget build(context) {
try{
if (isFirst == true) {
fetchImage();
fetchCategories(context);
isFirst = false;
}
}catch(Exception){
}
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.black,
appBar: AppBar(
title: Text('Lets see images!'),
),
body: new Column(
children: <Widget>[
new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new InkResponse(
child: new Column(
children: <Widget>[
Padding(
padding: EdgeInsets.all(10.0),
child: new Image.asset(
catimages[0],
width: 60.0,
height: 60.0,
),
),
new Text(
categoriesText[0],
style: TextStyle(color: Colors.white),
),
],
),
onTap: () {
debugPrint("on tv clikced");
widget.fetchApI.fetchSubCategories(context, 6);
}),
new InkResponse(
child: new Column(
children: <Widget>[
Padding(
padding: EdgeInsets.all(10.0),
child: new Image.asset(
catimages[1],
width: 60.0,
height: 60.0,
),
),
new Text(
categoriesText[1],
style: TextStyle(color: Colors.white),
),
],
),
onTap: () {
debugPrint("on moview clicked");
widget. fetchApI.fetchSubCategories(context, 7);
},
),
new InkResponse(
child: new Column(
children: <Widget>[
Padding(
padding: EdgeInsets.all(10.0),
child: new Image.asset(
catimages[2],
width: 60.0,
height: 60.0,
),
),
new Text(
categoriesText[2],
style: TextStyle(color: Colors.white),
),
],
),
onTap: () {
debugPrint("on news clicked");
widget.fetchApI.fetchSubCategories(context, 10);
},
),
new InkResponse(
child: new Column(
children: <Widget>[
Padding(
padding: EdgeInsets.all(10.0),
child: new Image.asset(catimages[3],
width: 60.0, height: 60.0),
),
new Text(
categoriesText[3],
style: TextStyle(color: Colors.white),
),
],
),
onTap: () {
debugPrint('on shows clicked');
widget.fetchApI.fetchSubCategories(context, 8);
},
),
new InkResponse(
child: new Column(
children: <Widget>[
Padding(
padding: EdgeInsets.all(10.0),
child: new Image.asset('assets/live_icon.png',
width: 60.0, height: 60.0),
),
new Text(
'Live',
style: TextStyle(color: Colors.white),
),
],
),
onTap: () {
debugPrint('on live clicked');
},
),
],
),
ImageList(images,widget.fetchApI),
],
),
),
);
}





Если вы извлекаете данные из API, рассмотрите возможность использования FutureBuilder.
Есть быстрый и грязный ответ, и правильный ответ
Используйте list?.elementAt(<index>) ?? "" для безопасного доступа к элементу списка
Widget build(context) {
try{
if (isFirst == true) {
fetchImage();
fetchCategories(context);
isFirst = false;
}
}catch(Exception){
}
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.black,
appBar: AppBar(
title: Text('Lets see images!'),
),
body: new Column(
children: <Widget>[
new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new InkResponse(
child: new Column(
children: <Widget>[
Padding(
padding: EdgeInsets.all(10.0),
child: new Image.asset(
catimages?.elementAt(0) ?? "",
width: 60.0,
height: 60.0,
),
),
new Text(
categoriesText?.elementAt(0) ?? "",
style: TextStyle(color: Colors.white),
),
],
),
onTap: () {
debugPrint("on tv clikced");
widget.fetchApI.fetchSubCategories(context, 6);
}),
new InkResponse(
child: new Column(
children: <Widget>[
Padding(
padding: EdgeInsets.all(10.0),
child: new Image.asset(
catimages?.elementAt(1) ?? "",
width: 60.0,
height: 60.0,
),
),
new Text(
categoriesText?.elementAt(1) ?? "",
style: TextStyle(color: Colors.white),
),
],
),
onTap: () {
debugPrint("on moview clicked");
widget. fetchApI.fetchSubCategories(context, 7);
},
),
new InkResponse(
child: new Column(
children: <Widget>[
Padding(
padding: EdgeInsets.all(10.0),
child: new Image.asset(
catimages?.elementAt(2) ?? "",
width: 60.0,
height: 60.0,
),
),
new Text(
categoriesText?.elementAt(2) ?? "",
style: TextStyle(color: Colors.white),
),
],
),
onTap: () {
debugPrint("on news clicked");
widget.fetchApI.fetchSubCategories(context, 10);
},
),
new InkResponse(
child: new Column(
children: <Widget>[
Padding(
padding: EdgeInsets.all(10.0),
child: new Image.asset(catimages?.elementAt(3) ?? "",
width: 60.0, height: 60.0),
),
new Text(
categoriesText?.elementAt(3) ?? "",
style: TextStyle(color: Colors.white),
),
],
),
onTap: () {
debugPrint('on shows clicked');
widget.fetchApI.fetchSubCategories(context, 8);
},
),
new InkResponse(
child: new Column(
children: <Widget>[
Padding(
padding: EdgeInsets.all(10.0),
child: new Image.asset('assets/live_icon.png',
width: 60.0, height: 60.0),
),
new Text(
'Live',
style: TextStyle(color: Colors.white),
),
],
),
onTap: () {
debugPrint('on live clicked');
},
),
],
),
ImageList(images,widget.fetchApI),
],
),
),
);
}
}
Честно говоря, если бы мне пришлось просмотреть этот код, даже если бы он работал безупречно, я бы отклонил это изменение, потому что структура/шаблон, который использует этот код, довольно плоха.
Вместо этого используйте FutureBuilder, StreamBuilder или ValueListenableBuilder, но вам нужно предоставить больше кода (особенно fetchImage и fetchCategories), чтобы мы могли помочь.
Обязательно укажите длину списка данных. Например, если вы используете ListView.builder, укажите правильное значение атрибута itemCount.
ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (ctx, index) {
return WidgetItem();
});
Вы не получаете данные. Папка данных из или источник данных отсутствует. То же самое произошло и со мной. Позже я создал файл json для данных и указал на это место. И починили просто!
Для меня переход в каталог проекта и запуск команды flutter clean исправили ошибку
Проблема может заключаться в том, что вы пытаетесь получить доступ к переменной/массиву, который еще не готов (возможно, потому, что вызов future/api не завершен)
Быстрым обходным решением может быть проверка длины массива или проверка на нуль, например:
Text( (myArray?.length > 0 ? myArray[0] : '') );
Я предполагаю, что вы получаете данные из метода fetchApI, если вы получаете данные в методе fetchApI. тогда вы должны следовать этому
fetchApI и является методом asynchronous, поэтому для получения данных из json требуется время, а в начале fetchApI пуст, поэтому выдает ошибку диапазона.
вы можете создать метод fetchApI asynchronous, используя await и async*, и при вызове этого метода используйте метод .then, а затем получите доступ к значениям.
fetchApI().then((){ // access fetchApI over here });
Если другие методы не работают, проверьте, содержит ли ваша база данных конфликтующие записи данных. Если это так, исправьте их.
Причина ошибки:
Эта ошибка возникает при получении значения индекса, которого нет в List. Например:
List<int> list = [];
list[0]; // <-- Error since there's no element at index 0 in the list.
Решение:
Проверьте, не является ли Listnull и содержит элемент по индексу:
var myList = nullableList;
var index = 0;
if (myList != null && myList.length > index) {
myList[index]; // You can safely access the element here.
}
У меня возникла такая же проблема при попытке доступа к пустому массиву. Это было частью нулевой безопасности.
мой предыдущий код был
TextBox(response.customerDetails!.address![0].city),
что вызвало у меня ошибку, поэтому я изменил код на
Text(
(response.cutomerDetails.address.isNotEmpty)
? response.customerDetails!.address![0].city
: "N/A",
),
добавить проверку при доступе к массивам. Это помогло мне убрать ошибку.