【问题标题】:Flutter DataTable LayoutFlutter 数据表布局
【发布时间】:2021-05-06 09:43:48
【问题描述】:

我在 Flutter 中使用 FutureBuilderDataTable 有一些布局问题,我调用了 API,它自然会这样显示:

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

所以,First NameLast NameDelete 列总是相同的,它只是像上面第二张图片那样映射出表格行单元格。

这是否可以通过DataTable 使用FutureBuilder 来实现这一点,就像在我的示例中一样?

我尝试在 DataRow 单元格中使用 future builder,因为 DataCell 的每个孩子都是一个小部件,但它看起来真的很可怕,我不确定这是不是正确的做法......

代码如下:

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"],
    );
  }
}

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

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();
            },
          ),
        ),
      ],
    );
  }
}

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

【问题讨论】:

    标签: flutter mobile flutter-layout flutter-futurebuilder flutter-table


    【解决方案1】:

    第 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();
                }
              },
            )),
          ),
        );
      }
    

    【讨论】:

    • 谢谢!作为参考,您的解决方案是正确的,但它仍然返回另一个表,但您的回答让我意识到我的错误,我只需将itemCount 放入1! :) 再次感谢!
    猜你喜欢
    • 2021-04-27
    • 2021-07-18
    • 2021-08-17
    • 2013-05-21
    • 1970-01-01
    • 1970-01-01
    • 2021-08-08
    • 2019-05-06
    • 2020-06-11
    相关资源
    最近更新 更多