Flutter 数据表布局

Flutter DataTable Layout

我在带有 FutureBuilder 的 Flutter 中遇到 DataTable 的一些布局问题,我调用了 API,它自然会这样显示:

可以理解,因为我正在构建一个 table 的列表,它将 return 多个 table 返回。我只想将行映射为列表,列应该保持不变,就像这样:

因此,First NameLast NameDelete 列始终相同,它只是映射出 table 行单元格,如上面第二张图片所示。

是否可以像我的示例中那样使用 FutureBuilder 通过 DataTable 实现此目的?

我试过在 DataRow 单元格中使用 future builder,因为 DataCell 的每个 child 都是一个 Widget,但它看起来真的很糟糕,我不确定这是正确的做法...

代码如下:

API调用:

import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'models/names.dart';

Future<List<NameData>> fetchNames() async {
  List<NameData> names = List();
  final response = await http.get('https://jsonplaceholder.typicode.com/posts');

  if (response.statusCode == 200) {
    // If the server did return a 200 OK response,
    // then parse the JSON.
    var namesJson = jsonDecode(response.body);
    print(response.body);
    for (int i = 0; i < namesJson.length; i++) {
      names.add(NameData.fromJson(jsonDecode(response.body)[i]));
    }
    return names;
  } else {
    // If the server did not return a 200 OK response,
    // then throw an exception.
    throw Exception('Failed to load names');
  }
}

姓名模型:

import 'package:flutter/foundation.dart';
import 'dart:core';

class NameData extends ChangeNotifier {
  final int id;
  final int userId;
  final String title;
  final String body;

  NameData({
    this.id,
    this.userId,
    this.title,
    this.body,
  });

  factory NameData.fromJson(Map<String, dynamic> json) {
    return NameData(
      id: json["id"],
      userId: json["userId"],
      title: json["title"],
      body: json["body"],
    );
  }
}

以及带有数据的名称列表 table:

import 'package:flutter/material.dart';
import 'models/names.dart';
import 'services/name_api.dart';

class NameList extends StatefulWidget {
  @override
  _NameList createState() => _NameList();
}

class _NameList extends State<NameList> {
  Future<List<NameData>> futureNames;

  @override
  void initState() {
    super.initState();
    futureNames = fetchNames();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        SizedBox(
          height: 600,
          child: FutureBuilder<List<NameData>>(
            future: futureNames,
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                return ListView.builder(
                  itemCount: snapshot.data.length,
                  itemBuilder: (context, index) {
                    return Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      mainAxisAlignment: MainAxisAlignment.spaceAround,
                      children: [
                        SizedBox(
                          height: 12.0,
                        ),
                        Container(
                          decoration: BoxDecoration(
                            color: Colors.grey[300],
                            borderRadius: BorderRadius.all(
                              Radius.circular(12.0),
                            ),
                          ),
                          child: SingleChildScrollView(
                            scrollDirection: Axis.horizontal,
                            child: DataTable(
                              columns: <DataColumn>[
                                DataColumn(
                                  label: Text(
                                    'First Name',
                                    style:
                                        TextStyle(fontStyle: FontStyle.italic),
                                  ),
                                ),
                                DataColumn(
                                  label: Text(
                                    'Last Name',
                                    style:
                                        TextStyle(fontStyle: FontStyle.italic),
                                  ),
                                ),
                                DataColumn(
                                  label: Text(
                                    'Delete',
                                    style:
                                        TextStyle(fontStyle: FontStyle.italic),
                                  ),
                                ),
                              ],
                              rows: <DataRow>[
                                DataRow(
                                  cells: <DataCell>[
                                    DataCell(
                                        Text('${snapshot.data[index].id}')),
                                    DataCell(
                                        Text('${snapshot.data[index].userId}')),
                                    DataCell(Icon(Icons.delete)),
                                  ],
                                ),
                              ],
                            ),
                          ),
                        ),
                        SizedBox(
                          height: 16.0,
                        ),
                      ],
                    );
                  },
                );
              } else if (snapshot.hasError) {
                return Text("${snapshot.error}");
              }
              return Container();
            },
          ),
        ),
      ],
    );
  }
}

提前感谢您的宝贵时间和帮助。

第 1 步:

 Future<List<NameData>> generateList() async {
    final response =
        await http.get('https://jsonplaceholder.typicode.com/posts');

    var list = await json.decode(response.body).cast<Map<String, dynamic>>();
    return await list.map<NameData>((json) => NameData.fromJson(json)).toList();
  }

第 2 步:

@override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        appBar: AppBar(
          title: Text('DataTable'),
        ),
        body: Container(
            child: FutureBuilder<List<NameData>>(
          future: generateList(),
          builder: (context, snapShot) {
            if (snapShot.hasData) {
              return SingleChildScrollView(
                scrollDirection: Axis.horizontal,
                child: DataTable(
                  columns: <DataColumn>[
                    DataColumn(
                      label: Text(
                        'First Name',
                        style: TextStyle(fontStyle: FontStyle.italic),
                      ),
                    ),
                    DataColumn(
                      label: Text(
                        'Last Name',
                        style: TextStyle(fontStyle: FontStyle.italic),
                      ),
                    ),
                    DataColumn(
                      label: Text(
                        'Delete',
                        style: TextStyle(fontStyle: FontStyle.italic),
                      ),
                    ),
                  ],
                  rows: snapShot.data.map<DataRow>((e) {
                    return DataRow(
                      cells: <DataCell>[
                        DataCell(Text('${e.id}')),
                        DataCell(Text('${e.userId}')),
                        DataCell(Icon(Icons.delete)),
                      ],
                    );
                  }).toList(),
                ),
              );
            }else{
              return CircularProgressIndicator();
            }
          },
        )),
      ),
    );
  }