Если вы создаете новый проект Flutter и включаете зависимости, а затем заменяете свой файл main.dart, вы должны быть там, где я нахожусь по этому вопросу.


Я оставил исходную загрузку: с Future.delayed, но это не имеет значения. Я частично знаю, в чем заключается моя проблема, но не могу найти лучшего решения.

1) Кажется, я не использую свой snapshot.data, а просто создаю пустой список с str, а затем просто добавляю в него все и использую его. Поэтому я бы не хотел этого делать, изначально я использовал snapshot.data, но столкнулся с проблемами, когда попытался «загрузить дополнительные данные», что происходит после прокрутки вниз списка.

Проблема в моем текущем методе заключается в том, что если вы загружаете больше пользователей, а затем пытаетесь выполнить повторную загрузку, прежде чем пользователи загрузятся, приложение разрывается и не ожидает правильного отображения данных нагрузить . Я считаю, что мне нужно делать все это в load: этой библиотеки easy_refresh ... но я не уверен, как переписать мой код для достижения этой цели.

Как получить данные для загрузки с помощью snapshot.data, а затем, когда я обновляю данные, я добавляю в этот список еще 100 пользователей, но пользовательский интерфейс ожидает обновления списка до завершения загрузки. Было бы лучше, если бы я поместил элемент пользовательского интерфейса Blocking и после обновления списка str? и когда новые пользователи загружаются, я разблокирую интерфейс? какая Сорта чувствует себя хакером и не правильный способ решить это. Сам плагин должен быть в состоянии выполнить загрузку, и когда он будет готов, он останавливает спиннер под списком и говорит «готово».

< Сильный > pubspec.yaml

dependencies:
flutter:
  sdk: flutter

flutter_easyrefresh: ^1.2.7
http: ^0.12.0+2

main.dart

  import 'package:flutter/material.dart';
  import 'dart:async';
  import 'dart:convert';
  import 'package:flutter_easyrefresh/easy_refresh.dart';
  import 'package:http/http.dart' as http;

  void main() => runApp(MyApp());

  class MyApp extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
      return MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
          backgroundColor: Colors.white
        ),
        home: DuelLeaderBoards(),
      );
    }
  }


  class DuelLeaderBoards extends StatefulWidget {
    @override
    _DuelLeaderBoardsState createState() => _DuelLeaderBoardsState();
  }

  class _DuelLeaderBoardsState extends State<DuelLeaderBoards> {
    List<Entry> str = [];
    GlobalKey<EasyRefreshState> _easyRefreshKey = new GlobalKey<EasyRefreshState>();
    GlobalKey<RefreshHeaderState> _headerKey = new GlobalKey<RefreshHeaderState>();
    GlobalKey<RefreshHeaderState> _connectorHeaderKey = new GlobalKey<RefreshHeaderState>();
    GlobalKey<RefreshFooterState> _footerKey = new GlobalKey<RefreshFooterState>();
    GlobalKey<RefreshFooterState> _connectorFooterKey = new GlobalKey<RefreshFooterState>();

    Future<LeaderBoards> getLeaderBoards(start) async {
      String apiURL = 'https://stats.quake.com/api/v2/Leaderboard?from=$start&board=duel&season=current';

      final response = await http.get(apiURL);
      if (response.statusCode == 200) {
        final responseBody = leaderBoardsFromJson(response.body);
        return responseBody;
      } else {
        throw Exception('Failed to load Data');
      }
    }

    void updateLeaderBoardList(e) async {
      setState(() {
        str.addAll(e.entries);
      });
    }

    @override
    void initState() {
      getLeaderBoards(0).then((onValue) => str = onValue.entries );
      super.initState();
    }

    @override
    Widget build(BuildContext context) {
      Widget header = ClassicsHeader(
        key: _headerKey,
        refreshText: "pullToRefresh",
        refreshReadyText: "releaseToRefresh",
        refreshingText: "refreshing...",
        refreshedText: "refreshed",
        moreInfo: "updateAt",
        bgColor: Colors.transparent,
        textColor: Colors.white,
      );
      Widget footer = ClassicsFooter(
        key: _footerKey,
        loadHeight: 50.0,
        loadText: "pushToLoad",
        loadReadyText: "releaseToLoad",
        loadingText: "loading",
        loadedText: "loaded",
        noMoreText: "Finished",
        moreInfo: "updateAt",
        bgColor: Colors.transparent,
        textColor: Colors.white,
      );
      return FutureBuilder(
          future: getLeaderBoards(0),
          builder:
              (BuildContext context, AsyncSnapshot<LeaderBoards> snapshot) {
            if (!snapshot.hasData) {
              return Center(
                child: CircularProgressIndicator(),
              );
            } else {
              return Builder(builder: (BuildContext context) {
                return Center(
                    child: new EasyRefresh(
                      key: _easyRefreshKey,
                      behavior: ScrollOverBehavior(),
                      refreshHeader: ConnectorHeader(
                        key: _connectorHeaderKey,
                        header: header,
                      ),
                      refreshFooter: ConnectorFooter(
                        key: _connectorFooterKey,
                        footer: footer,
                      ),
                      child: CustomScrollView(
                        semanticChildCount: str.length,
                        slivers: <Widget>[
                          SliverList(
                            delegate: SliverChildListDelegate(<Widget>[header]),
                          ),
                          SliverList(
                              delegate: SliverChildBuilderDelegate(
                                    (context, index) {
                                      return new Container(
                                          height: 70.0,
                                          child: Card(
                                            child: new Text(
                                              '${index+1}: ${str[index].userName}',
                                              style: new TextStyle(fontSize: 18.0),
                                            ),
                                          ));
                                },
                                childCount: str.length,
                              )),
                          SliverList(
                            delegate: SliverChildListDelegate(<Widget>[footer]),
                          )
                        ],
                      ),
                      onRefresh: () async {
                        await new Future.delayed(const Duration(seconds: 0), () {
                          setState(() {});
                        });
                      },
                      loadMore: () async {
                        getLeaderBoards(str.length).then((onValue) => {
                        updateLeaderBoardList(onValue)
                        });
                      },
  //                    loadMore: () async {
  //                      await new Future.delayed(const Duration(seconds: 0), () {
  //                        getLeaderBoards(str.length).then((onValue) => {
  //                              updateLeaderBoardList(onValue)
  //                        });
  //                      });
  //                    },
                    )
                );
              });
            }
          });
    }
  }



  LeaderBoards leaderBoardsFromJson(String str) {
    final jsonData = json.decode(str);
    return LeaderBoards.fromJson(jsonData);
  }

  String leaderBoardsToJson(LeaderBoards data) {
    final dyn = data.toJson();
    return json.encode(dyn);
  }

  class LeaderBoards {
    String boardType;
    List<Entry> entries;
    int totalEntries;

    LeaderBoards({
      this.boardType,
      this.entries,
      this.totalEntries,
    });

    factory LeaderBoards.fromJson(Map<String, dynamic> json) => new LeaderBoards(
      boardType: json["boardType"] == null ? null : json["boardType"],
      entries: json["entries"] == null ? null : new List<Entry>.from(json["entries"].map((x) => Entry.fromJson(x))),
      totalEntries: json["totalEntries"] == null ? null : json["totalEntries"],
    );

    Map<String, dynamic> toJson() => {
      "boardType": boardType == null ? null : boardType,
      "entries": entries == null ? null : new List<dynamic>.from(entries.map((x) => x.toJson())),
      "totalEntries": totalEntries == null ? null : totalEntries,
    };
  }

  class Entry {
    String userName;
    int eloRating;
    String profileIconId;
    String namePlateId;

    Entry({
      this.userName,
      this.eloRating,
      this.profileIconId,
      this.namePlateId,
    });

    factory Entry.fromJson(Map<String, dynamic> json) => new Entry(
      userName: json["userName"] == null ? null : json["userName"],
      eloRating: json["eloRating"] == null ? null : json["eloRating"],
      profileIconId: json["profileIconId"] == null ? null : json["profileIconId"],
      namePlateId: json["namePlateId"] == null ? null : json["namePlateId"],
    );

    Map<String, dynamic> toJson() => {
      "userName": userName == null ? null : userName,
      "eloRating": eloRating == null ? null : eloRating,
      "profileIconId": profileIconId == null ? null : profileIconId,
      "namePlateId": namePlateId == null ? null : namePlateId,
    };
  }
0
Zuriel 15 Апр 2019 в 23:08

2 ответа

Лучший ответ

Я просмотрел документацию loadMore. Поскольку в нем говорится, что тело функции, назначенной для loadMore, должно быть async, вам не нужно использовать then:

loadMore: () async {
     final result = await getLeaderBoards(str.length);
     updateLeaderboardList(result);
},
0
Meysam 16 Апр 2019 в 05:26
loadMore: () async {
     await getLeaderBoards(str.length).then((onValue) => {
     updateLeaderboardList(onValue)
     });
},

Но, поставив «ожидание», мой загрузчик ждет завершения функции, прежде чем завершит анимацию.

0
Zuriel 16 Апр 2019 в 05:32