RangeError (index): Недопустимое значение: Допустимый диапазон значений пуст: 0

Я пытаюсь получить список из 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),
          ],
        ),
      ),
    );
  }
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
38
7
94 761
10

Ответы 10

Если вы извлекаете данные из 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",
),

добавить проверку при доступе к массивам. Это помогло мне убрать ошибку.

Другие вопросы по теме