flutter - 如何在Flutter中执行分页

标签 flutter dart pagination flutter-layout

我一直在浏览各种有关分页的文章,但似乎没有一篇对我有用。我正在使用的API端点如下所示
http://camx.heropp.com/api/connect?offset=0(这是一个示例链接,因此无法正常工作),而我发出请求时得到的响应如下所示

{
    "result": {
        "connectUsers": [
            {
                "_id": "5f6a412d2ea9350017bec99f",
                "userProfile": {
                    "rep_points": 0.75,
                    "visits": 0,
                    "bio": "Nothing for you ",
                    "gender": "Male",
                    "university": "University Of Technology",
                    "avatar": "https://camx.heroapp.com/5f6a412d2ea9350017bec99f"
                },
                "name": "Joseph Henshaw ",
                "userTag": "bigjo",
                "id": "5f6a412d2ea9350017bec99f",
                "sameCampus": true
            },
            {
                "_id": "5f6bbf1cbd5faa00170d92b1",
                "userProfile": {
                    "rep_points": 0,
                    "visits": 0
                },
                "name": "John Doe",
                "userTag": "@doee",
                "id": "5f6bbf1cbd5faa00170d92b1",
                "sameCampus": false
            }
        ]
    }
}
我想要实现的是对来自api..offset的数据进行分页。偏移量从0开始并以10增加,即获取更多数据0ffset = 20..30 ..依此类推
这是我要获取上面显示的JSON响应的请求
Future<void> fetchConnect() async {
    var uri = Uri.parse('http://campusx.herokuapp.com/api/v1/users/connect');
    uri = uri.replace(query: 'offset=$offsetNumber');
    print(uri);
    try {
      final response = await http.get(
        uri,
        headers: {
          HttpHeaders.authorizationHeader: "Bearer $userToken",
        },

      );
      // List<Photo> fetchedPhotos = Photo.parseList(json.decode(response.body));
      if (response.statusCode == 200 || response.statusCode == 201) {
         print("IT works")
      } else {
        print(response.statusCode);
      }
      List<ConnectUsers> fetchedConnects =
          ConnectUsers.parseList(json.decode(response.body));
      setState(() {
        connectMore = fetchedConnects.length == defaultConnectsPerPageCount;
        loading = false;
        offsetNumber = offsetNumber + 10;
        connects.addAll(fetchedConnects);
      });
    } catch (e) {
      setState(() {
        loading = false;
        error = true;
      });
    }
  }
这就是我用于显示数据的UI的方式(小部件getConnect放置在我的Scaffold主体中
 Widget getConnects() {
    if (connects.isEmpty) {
      if (loading) {
        return Center(
            child: Padding(
          padding: const EdgeInsets.all(8),
          child: CircularProgressIndicator(),
        ));
      } else if (error) {
        return Center(
            child: InkWell(
          onTap: () {
            setState(() {
              loading = true;
              error = false;
              fetchConnects();
            });
          },
          child: Padding(
            padding: const EdgeInsets.all(16),
            child: Text("Error while loading connects, tap to try again"),
          ),
        ));
      }
    } else {
      return ListView.builder(
          itemCount: connects.length + (connectMore ? 10 : 0),
          itemBuilder: (context, index) {
            if (index == connects.length - nextPageThreshold) {
              fetchConnects();
            }
            if (index == connects.length) {
              if (error) {
                return Center(
                    child: InkWell(
                  onTap: () {
                    setState(() {
                      loading = true;
                      error = false;
                      fetchConnects();
                    });
                  },
                  child: Padding(
                    padding: const EdgeInsets.all(16),
                    child:
                        Text("Error while loading connects, tap to try agin"),
                  ),
                ));
              } else {
                return Center(
                    child: Padding(
                  padding: const EdgeInsets.all(8),
                  child: CircularProgressIndicator(),
                ));
              }
            }
            // final Photo photo = photos[index];
            final ConnectUsers connect = connects[index];
            return Card(
              child: Column(
                children: <Widget>[
                  // Image.network(
                  //   connect.name.connectUsers[index].userProfile.avatar,
                  //   fit: BoxFit.fitWidth,
                  //   width: double.infinity,
                  //   height: 160,
                  // ),
                  Padding(
                    padding: const EdgeInsets.all(16),
                    child: Text(connect.name,
                        // connect
                        // .result.connectUsers[index].userProfile.university,
                        style: TextStyle(
                            fontWeight: FontWeight.bold, fontSize: 16)),
                  ),
                ],
              ),
            );
          });
    }
    return Container();
  }
这是我在使用此代码时遇到的错误
The getter 'isEmpty' was called on null.
Receiver: null
Tried calling: isEmpty

最佳答案

我已经解决了问题,这就是我使用的方式
这是我的model.dart类


import 'package:flutter/foundation.dart';

ConnectModel payloadFromJson(String str) =>
    ConnectModel.fromJson(json.decode(str));

String payloadToJson(ConnectModel data) => json.encode(data.toJson());

class ConnectModel {
  ConnectModel({
    this.result,
  });

  Result result;

  factory ConnectModel.fromJson(Map<String, dynamic> json) => ConnectModel(
        result: Result.fromJson(json["result"]),
      );

  Map<String, dynamic> toJson() => {
        "result": result.toJson(),
      };
}

class Result {
  Result({
    this.connect,
  });

  List<Connect> connect;

  factory Result.fromJson(Map<String, dynamic> json) => Result(
        connect: List<Connect>.from(
            json["connectUsers"].map((x) => Connect.fromJson(x))),
      );

  Map<String, dynamic> toJson() => {
        "connectUsers": List<dynamic>.from(connect.map((x) => x.toJson())),
      };
}

class Connect with ChangeNotifier {
  Connect({
    this.id,
    this.name,
    this.userTag,
    this.university,
    this.checkIsFollowing,
    this.avatar,
  });
  String name;
  String userTag;
  String id;
  String university;
  String avatar;
  bool checkIsFollowing;

  factory Connect.fromJson(Map<String, dynamic> json) => Connect(
        id: json["_id"],
        name: json["name"],
        userTag: json["userTag"],
        university: json["userProfile"]["university"],
        checkIsFollowing: json["checkIsFollowing"],
        avatar: json["userProfile"]["avatar"],
      );

  Map<String, dynamic> toJson() => {
        "_id": id,
        "name": name,
        "userTag": userTag,
        "userProfile"
            "university": university,
        "userProfile"
            "avatar": avatar,
        "checkIsFollowing": checkIsFollowing
      };
}
这是我的方法,其中offsetNumber默认情况下初始化为0
  List<Connect> mainList = [];
  List<String> nameList = [];
  Future<List<Connect>> getConnectionsList(var offsetNumber) async {
    var uri = "http://campusx.herokuapp.com/api/v1/users/connect?$offsetNumber";
    var token = "pass_your_token_here";
    try {
      final response =
          await http.get(uri, headers: {"Authorization": "Bearer $token"});
      if (response.statusCode == 200) {
        var data = json.decode(response.body);
        var d = data['result']['connectUsers'];
        for (var u in d) {
          Connect c = Connect.fromJson(u);
          mainList.add(c);
        }
        setState(() {
          nameList = mainList.map((e) => e.name).toList();
          //add other parameters gotten from the endpoint here, i used name only for test purposes
        });
      } else {
        print(response.body);
      }
    } catch (e) {
      print(e);
    }
    return mainList;
  }
这是ListView构建器,我在其中显示了名称
     ListView.builder(
          itemCount: mainList.length,
          itemBuilder: (_, index) {
            return Container(
              height: 120,
              child: Text(
                nameList[index],
                style: TextStyle(fontSize: 39),
               ),
            );
          },
       )

然后单击onClick或按钮,或者当列表到达电话屏幕的底部时,将设置setState((){});并增加offsetNumber的大小。像这样:
setState(() {
  offsetNumber = offsetNumber + 10;
  future = getConnectionsList(offsetNumber);
});

关于flutter - 如何在Flutter中执行分页,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64616789/

相关文章:

flutter - 如何在 google flutter 中对齐行中的文本小部件?

flutter - 为什么我收到错误,flutter statfulwidget flutter 中的常量值无效

firebase - 从firestore中获取用户数据,并使用flutter在配置文件屏幕中显示用户数据

ruby-on-rails-3 - Kaminari 和页面路由

flutter - Flutter:如何在Firestore中更新阵列中的阵列

flutter - 如何更改提升按钮主题中的提升按钮文本颜色?

javascript - Dart 中的镜子不适用于所有元素

无需 video_player 插件即可轻松播放本地视频

php - wordpress中自定义帖子类型的分页

php - 分页不显示