首页 > 解决方案 > 如何在脚手架块的 FutureBuilder 中实现 listview.builder?

问题描述

我想在列表视图中添加我的数据。还尝试使用此https://flutter.dev/docs/cookbook/lists/long-lists

我在futureAlbum 中有数据,快照有数据。但我无法在 listView.builder 中转换这些数据。那么,如何在 FutureBuilder 中实现 listview 呢?

body: Center(
        child: FutureBuilder<ListAlbum>(
          future: futureAlbum,
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              print(snapshot.data);
              return Text(snapshot.data!.idEmployee.toString()); // in this section i want to add listview
            } else if (snapshot.hasError) {
              return Text('${snapshot.error}');
            }
            return const CircularProgressIndicator();
          },
        ),
      ),

调用api的完整代码

class OrganizationList extends StatefulWidget {
  const OrganizationList({Key? key}) : super(key: key);

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

class _OrganizationListState extends State<OrganizationList> {
  late Future<ListAlbum> futureAlbum;

  @override
  void initState() {
    super.initState();
    futureAlbum = listData();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: FutureBuilder<ListAlbum>(
          future: futureAlbum,
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              print(snapshot.data);
              return Text(snapshot.data!.idEmployee.toString()); // in this section i want to add listview
            } else if (snapshot.hasError) {
              return Text('${snapshot.error}');
            }
            return const CircularProgressIndicator();
          },
        ),
      ),
    );
  }
}


class ListAlbum {
  final int idEmployee;
  final String avatar;
  final String fullName;
  final String officeID;
  final String email;
  final String designation;
  final String department;
  final String mobileNumber;
  final String workStation;
  final String businessUnit;

  ListAlbum({
    required this.idEmployee,
    required this.avatar,
    required this.fullName,
    required this.officeID,
    required this.email,
    required this.designation,
    required this.department,
    required this.mobileNumber,
    required this.workStation,
    required this.businessUnit,
  });

  factory ListAlbum.fromJson(Map<String, dynamic> json) {
    return ListAlbum(
      idEmployee: json['idEmployee'],
      avatar: json['avatar'],
      fullName: json['fullName'],
      officeID: json['officeID'],
      email: json['email'],
      designation: json['designation'],
      department: json['department'],
      mobileNumber: json['mobileNumber'],
      workStation: json['workStation'],
      businessUnit: json['businessUnit'],
    );
  }
}

Future<ListAlbum> listData() async {
  final token =
      'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjI4OTksImlzcyI6Imh0dHBzOi8vcG9ydGFsLWFwaS5qb21ha2hhdGEuY29tL2FwaS9hdXRoL2xvZ2luIiwiaWF0IjoxNjI5NTI2OTc1LCJleHAiOjE2Mjk2MTMzNzUsIm5iZiI6MTYyOTUyNjk3NSwianRpIjoiRktiT295eEYwaEpDUXMxdiJ9.o4eM_C4hlluHe9Azk0MspPJtYZ7agdpFA6xwKiijLj8';
  String url =
      'https://portal-api.jomakhata.com/api/getOrganizationData?token=${token}';

  Dio dio = new Dio();
  dio.options.headers['Content-Type'] = 'application/json';
  final body = {'limit': 5, 'orderBy': 'idEmployee', 'orderType': 'DESC'};
  final response = await dio.post(url, data: body);

  if (response.statusCode == 200) {
    print(response.statusCode);
    print(response.data);
    var data = ListAlbum.fromJson(response.data["data"]["data"][0]);
    return data;
  } else {
    throw Exception('Failed!');
  }
}

我要实施什么清单!

标签: flutterlistviewbuilder

解决方案


首先,您将所有成员都ListAlbum标记为必需,但您在响应中的某些结果并不包含所有这些,例如第二行没有avatar。您可以通过将这些字段标记为不需要来克服这个问题,就像这样(我在这里将所有成员设为可选 - 根据需要进行调整):

class ListAlbum {
  final int? idEmployee;
  final String? avatar;
  final String? fullName;
  final String? officeID;
  final String? email;
  final String? designation;
  final String? department;
  final String? mobileNumber;
  final String? workStation;
  final String? businessUnit;

  ListAlbum({
    this.idEmployee,
    this.avatar,
    this.fullName,
    this.officeID,
    this.email,
    this.designation,
    this.department,
    this.mobileNumber,
    this.workStation,
    this.businessUnit,
  });

  factory ListAlbum.fromJson(Map<String, dynamic> json) {
    return ListAlbum(
      idEmployee: json['idEmployee'],
      avatar: json['avatar'],
      fullName: json['fullName'],
      officeID: json['officeID'],
      email: json['email'],
      designation: json['designation'],
      department: json['department'],
      mobileNumber: json['mobileNumber'],
      workStation: json['workStation'],
      businessUnit: json['businessUnit'],
    );
  }
}

接下来,转换您的listData函数,使其返回对象列表ListAlbum您可以从响应中获取数据,转换并返回,如下所示:

Future<List<ListAlbum>> listData() async {
  final token =
      'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjI4OTksImlzcyI6Imh0dHBzOi8vcG9ydGFsLWFwaS5qb21ha2hhdGEuY29tL2FwaS9hdXRoL2xvZ2luIiwiaWF0IjoxNjI5NTI2OTc1LCJleHAiOjE2Mjk2MTMzNzUsIm5iZiI6MTYyOTUyNjk3NSwianRpIjoiRktiT295eEYwaEpDUXMxdiJ9.o4eM_C4hlluHe9Azk0MspPJtYZ7agdpFA6xwKiijLj8';
  String url =
      'https://portal-api.jomakhata.com/api/getOrganizationData?token=${token}';

  Dio dio = new Dio();
  dio.options.headers['Content-Type'] = 'application/json';
  final body = {'limit': 5, 'orderBy': 'idEmployee', 'orderType': 'DESC'};
  final response = await dio.post(url, data: body);

  if (response.statusCode == 200) {
    print(response.statusCode);
    print(response.data);

    return response.data["data"]["data"]
        .map<ListAlbum>((json) => ListAlbum.fromJson(json))
        .toList();
  } else {
    throw Exception('Failed!');
  }
}

最后,更改未来返回类型并ListView从此列表创建,这是一个示例,调整它:

class _OrganizationListState extends State<OrganizationList> {
  late Future<List <ListAlbum>> futureAlbum;

  @override
  void initState() {
    super.initState();
    futureAlbum = listData();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Center(
      child: FutureBuilder<List<ListAlbum>>(
        future: futureAlbum,
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            print(snapshot.data);

            return ListView.builder(
              itemCount: snapshot.data!.length,
              itemBuilder: (context, index) {
                final ListAlbum item = snapshot.data![index];
                return ListTile(
                  leading: Text(item.idEmployee.toString()),
                  title: Text(item.fullName!),
                  subtitle: Text(item.designation!),
                  trailing: Text(item.businessUnit!),
                );
              },
            );
          } else if (snapshot.hasError) {
            return Text('${snapshot.error}');
          }
          return const CircularProgressIndicator();
        },
      ),
    ));
  }
}

......我不知道是否token是秘密,但如果是,你应该撤销它。


推荐阅读