FutureBuilderState # a0d90): I / flutter (20935): RangeError (index): Invalid value: допустимый диапазон значений пуст: 0 - PullRequest
0 голосов
/ 27 мая 2020

Я получаю данные категории из своего API. Раньше я использовал жестко запрограммированные данные JSON, поэтому они отлично работали в приложении, но теперь, когда я использую данные API, он показывает эту ошибку:

The following RangeError was thrown building FutureBuilder<List<Category>>(dirty, state:
I/flutter (20935): _FutureBuilderState<List<Category>>#a0d90):
I/flutter (20935): RangeError (index): Invalid value: Valid value range is empty:

Это мой код:

    import 'dart:convert';
    import 'package:flutter/material.dart';
    import 'package:news/explore/search_data.dart';
    import 'package:news/models/category.dart';
    import 'package:news/models/user.dart';

    import 'package:news/video/pages/health_page.dart';

    import 'package:http/http.dart' as http;
    import 'package:news/api/api.dart';

    Widget getErrorWidget(BuildContext context, FlutterErrorDetails error) {
    return Center(
      child: Text(
        "Loadingg........................",
        style: Theme.of(context).textTheme.title.copyWith(color: Colors.white),
        ),
      // child: CircularProgressIndicator(),
    );
    }

    class MyApp extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
      ErrorWidget.builder = (FlutterErrorDetails errorDetails) {
      return getErrorWidget(context, errorDetails);
      };
      return MaterialApp(
        title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: VideoPage(),
    );
  }
}

    class VideoPage extends StatefulWidget {
    @override
    _VideoPageState createState() => _VideoPageState();
    }

  class _VideoPageState extends State<VideoPage>
    with SingleTickerProviderStateMixin {
    List<User> userList = List<User>();

    int userID = 0;

    List<Category> categoryList = List<Category>();
    int id = 0;
    ValueNotifier<int> valueNotifier = ValueNotifier(0);
    List<Widget> _generateWidgets = List<Widget>();
    List<Tab> tabs = new List<Tab>();
    static List<Action> _action = <Action>[
    Action(
      title: 'Upload',
      icon: Icons.file_upload,
    ),
    Action(
      title: 'Moment',
      icon: Icons.contact_mail,
    ),
    Action(
      title: 'Article',
      icon: Icons.library_books,
    ),
    Action(
      title: 'Video',
      icon: Icons.video_call,
    )
  ];

  Action selectedAction = _action[0];

  TabController tabController;
  void initState() {
    super.initState();
  }

  Future<List<Category>> getCategory() async {
    await Future.delayed(Duration(seconds: 2));
    List<Category> categorys = List<Category>();
    var url = Api.GETCATEGORY_URL;
    var res = await http.get(url);
    if (res.statusCode == 200) {
      var data = jsonDecode(res.body);

      for (int i = 0; i < data.length; i++) {
        Category category = Category(data[i]['Categoryid'],
            data[i]['Categoryname'], data[i]['Categoryorder']);
        categorys.add(category);
        // SQLiteDbProvider.db.insertCategory(category);
      }
      print(data);
    }
    return categorys;
  }

  @override
  void dispose() {
    super.dispose();
  }

  void _onSelected(Action action) {
    setState(() {
      selectedAction = action;
      Navigator.push(context,
          MaterialPageRoute(builder: (context) => selectedAction.widget));
    });
  }

  List<Widget> getWidgets() {
    _generateWidgets.clear();

    return _generateWidgets;
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<List<Category>>(
      future: getCategory(),
      builder: (c, AsyncSnapshot<List<Category>> s) {
        if (s.hasData) {
          for (int i = 0; i < s.data.length; i++) {
            Category category = s.data[i];
            tabs.add(Tab(
              child: Text(
                category.categoryName,
                style: TextStyle(color: Colors.white),
              ),
            ));
            _generateWidgets.add(HealthPage(
              id: categoryList[i].categoryID,
            ));
          }

          return DefaultTabController(
              initialIndex: valueNotifier.value,
              length: s.data.length,
              child: Scaffold(
                appBar: AppBar(
                  title: GestureDetector(
                    onTap: () => showSearch(
                        context: context, delegate: SearchBarDelegate()),
                    child: new Container(
                      width: 400.0,
                      height: 40.0,
                      padding: EdgeInsets.only(left: 10.0),
                      decoration: BoxDecoration(
                        border: Border.all(
                          color: Colors.white,
                          width: 2.0,
                        ),
                        borderRadius: BorderRadius.circular(10.0),
                        color: Colors.white,
                      ),
                      child: Row(
                        children: <Widget>[
                          Icon(
                            Icons.search,
                            color: Colors.black26,
                          ),
                          SizedBox(
                            width: 10.0,
                          ),
                          Text(
                            'Search...',
                            style: TextStyle(
                              color: Colors.black26,
                              fontSize: 15.0,
                            ),
                          ),
                        ],
                      ),
                    ),
                  ),
                  actions: <Widget>[
                    Theme(
                      data: Theme.of(context).copyWith(
                        cardColor: Colors.black,
                      ),
                      child: PopupMenuButton(
                        itemBuilder: (BuildContext context) {
                          return _action.map((Action action) {
                            return PopupMenuItem(
                              value: action,
                              child: Container(
                                width: 75.0,
                                color: Colors.black,
                                child: Row(
                                  children: <Widget>[
                                    Icon(
                                      action.icon,
                                      color: Colors.white,
                                      size: 20.0,
                                    ),
                                    SizedBox(
                                      width: 3.0,
                                    ),
                                    Text(
                                      action.title,
                                      style: TextStyle(
                                          fontSize: 13.0, color: Colors.white),
                                    ),
                                  ],
                                ),
                              ),
                            );
                          }).toList();
                        },
                        icon: Icon(
                          Icons.add_a_photo,
                          color: Colors.white,
                        ),
                        offset: Offset(0, 100),
                        onSelected: _onSelected,
                      ),
                    ),
                  ],
                  bottom: TabBar(
                    isScrollable: true,
                    tabs: tabs,
                  ),
                ),
                body: TabBarView(
                  children: List.generate(
                    s.data.length,
                    (index) => _generateWidgets[index],
                  ),
                ),
              ));
        }
        return Center(
          child: CircularProgressIndicator(),
        );
      },
    );
  }
}

class Action {
  final String title;
  final IconData icon;
  final Widget widget;
  const Action({this.title, this.icon, this.widget});
}

class VideoCategory {
  final int id;
  final String name;
  VideoCategory({this.id, this.name});
}
...