Индексирование в Listview.builder

Nov 11 2020

Ответ, который я получаю от моего REST api, выглядит так

{
    "result": {
        "newsfeed": [
            {
                "_id": "5fa52495f0e30a0017f4dccf",
                "video": null,
                "image": null,
                "author": [
                    {
                        "_id": "5f6a412d2ea9350017bec99f",
                        "userProfile": {
                            "visits": 0,
                            "bio": "Nothing for you ",
                            "gender": "Male",
                            "university": "Bells University Of Technology"
                        },
                        "name": "Jo Shaw ",
                        "__v": 0
                    }
                ],
                "text": "have you seen this ?",
                "campus": "Technology",
                "isLiked": false
            }
        ]
    }
}

Я использую FutureBuilder для обработки выборки данных, а FutureBuilder возвращает ListView.builder, который я использую для создания своего макета в зависимости от количества элементов в ответе.

Это код моего интерфейса

     return Scaffold(
        body: FutureBuilder<TimelineModel>(
          future: _future,
          builder: (context, snapshot) {
            switch (snapshot.connectionState) {
              case ConnectionState.none:
                return Text('none');
              case ConnectionState.waiting:
                return Center(
                  child: CircularProgressIndicator(),
                );
              case ConnectionState.active:
                return Text('');
              case ConnectionState.done:
                if (snapshot.hasError || snapshot.data == null) {
                  return Scaffold(
                    backgroundColor: Theme.of(context).backgroundColor,
                    body: Column(
                      children: [
                        Container(
                          child: Center(
                            child: Text("It's empty here"),
                          ),
                        ),
                      ],
                    ),
                  );
                }  else {
                  print("length: " +
                      snapshot.data.result.newsfeed.length.toString());
                  return RefreshIndicator(
                    onRefresh: _getData,
                    child: ListView(
                      children: [
                        ListView.builder(
                            itemCount: snapshot.data.result.newsfeed.length,
                            itemBuilder: (context, index) {
                              return Column(
                                      children: <Widgets>[
//This line of code works properly and no error is gotten 
                                    Text( snapshot.data.result.newsfeed[index].text),

//Once I put in this line of code, i receive a range error (RangeError (index): Invalid value: Only valid value is 0: 1)
                                  Text(snapshot.data.result.newsfeed[index].author[index].name),
                                 ],
                              );
                           }
                         )
                       ]
                     )
                   )
                 }
               }
             }
           )
         );

Это ошибка, наблюдаемая, когда я пытаюсь сделать snapshot.data.result.newsfeed [index] .author [index] .name или использовать любой из элементов объекта внутри массива авторов

Ответы

1 Pro Nov 12 2020 at 23:12

Как упоминалось в @xion, вы используете newsfeedиндекс для authorмассива. Что вам следует сделать, так это назначить всех авторов в каждом newsfeedэлементе строке, а затем вместо этого использовать это значение. Ниже приведен код, который дает вам представление о том, что вам следует делать. Поскольку у меня нет доступа к вашему API, я жестко запрограммировал ваш ответ json.

class MyApp extends StatefulWidget {
  MyApp({Key key, this.title}) : super(key: key);

  final String title;

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

class MyAppState extends State<MyApp> {
  var testJson = json.decode('''
  {
    "result": {
      "newsfeed": [
        {
          "_id": "5fa52495f0e30a0017f4dccf",
          "video": null,
          "image": null,
          "author": [
            {
              "_id": "5f6a412d2ea9350017bec99f",
              "userProfile": {
                "visits": 0,
                "bio": "Nothing for you ",
                "gender": "Male",
                "university": "Bells University Of Technology"
              },
              "name": "Jo Shaw ",
              "__v": 0
            },
            {
              "_id": "5f6a412d2ea9350017bec99f",
              "userProfile": {
                "visits": 0,
                "bio": "Nothing for you ",
                "gender": "Male",
                "university": "Bells University Of Technology"
              },
              "name": "Jo Shaw ",
              "__v": 0
            }
          ],
          "text": "have you seen this ?",
          "campus": "Technology",
          "isLiked": false
        }
      ]
    }
  }
  ''');

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
            appBar: AppBar(
              title: Text(widget.title),
            ),
            body: Center(
              child: ListView(children: [
                ListView.builder(
                    scrollDirection: Axis.vertical,
                    shrinkWrap: true,
                    itemCount: testJson["result"]["newsfeed"].length,
                    itemBuilder: (context, index) {
                      String authors = '';
                      List<dynamic> authorsArray = testJson["result"]["newsfeed"][index]["author"];
                      for (int i = 0; i < authorsArray.length; i++) {
                        authors += i == (authorsArray.length - 1) ? authorsArray[i]["name"].toString() : authorsArray[i]["name"].toString() + ", ";
                      }
                      return Column(
                        children: [
                          Padding(
                            padding: EdgeInsets.all(10.0),
                            child: Text(
                              "Title: " +
                                  testJson["result"]["newsfeed"][index]["text"],
                              style: TextStyle(
                                  fontWeight: FontWeight.bold, fontSize: 18.0),
                            ),
                          ),
                          Text("Authors: " + authors,
                              style: TextStyle(
                                  color: Colors.black54,
                                  fontStyle: FontStyle.italic)),
                        ],
                      );
                    }),
              ]),
            ),
        ),
    );
  }
}

Скриншот:

xion Nov 12 2020 at 07:03

ваш автор обращается к тому же индексу, что и ваша лента новостей

возможно, вам понадобится еще один цикл для вашего автора

 ListView.builder(
                            itemCount: snapshot.data.result.newsfeed.length,
                            itemBuilder: (context, index) {
                              return Column(
                                      children: <Widgets>[
                                    Text( snapshot.data.result.newsfeed[index].text),
Text(snapshot.data.result.newsfeed[index].author[index].name), // <--- this line author[Index] hits error, not news the newsfeed
                                 ],
                              );
                           }
                         )