【问题标题】:Display firestore data with flutter in a DataTable在 DataTable 中显示带有颤动的 Firestore 数据
【发布时间】:2020-03-08 05:30:26
【问题描述】:

我正在尝试 Flutter 官方文档中的 Firebase for Flutter 示例应用程序,并将“ListTile”小部件更改为“DataTable”,现在 DataTable 正在为每个 DataRow 打印一个单独的 Datacolumn。 ‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎ ‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎ 请查看当前的Output screenshotDatabase la‎‎‎‎‎‎‎‎‎‎‎yout。‎‎ ‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎ ‎

    import 'package:cloud_firestore/cloud_firestore.dart';
    import 'package:flutter/material.dart';

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

    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Baby Names',
          home: MyHomePage(),
        );
      }
    }

    class MyHomePage extends StatefulWidget {
      @override
      _MyHomePageState createState() {
        return _MyHomePageState();
      }
    }

    class Record {
      final String name;
      final String rName;
      final int votes;
      final DocumentReference reference;

      Record.fromMap(Map<String, dynamic> map, {this.reference})
          : assert(map['name'] != null),
            assert(map['r_name'] != null),
            assert(map['votes'] != null),
            name = map['name'],
            rName = map['r_name'],
            votes = map['votes'];

      Record.fromSnapshot(DocumentSnapshot snapshot)
          : this.fromMap(snapshot.data, reference: snapshot.reference);

      @override
      String toString() => "Record<$name:$votes:$rName>";
    }

    class _MyHomePageState extends State<MyHomePage> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: Text('Baby Name Votes')),
          body: _buildBody(context),
        );
      }

      Widget _buildBody(BuildContext context) {
        return StreamBuilder<QuerySnapshot>(
          stream: Firestore.instance.collection('baby').snapshots(),
          builder: (context, snapshot) {
            if (!snapshot.hasData) return LinearProgressIndicator();

            return _buildList(context, snapshot.data.documents);
          },
        );
      }

      Widget _buildList(BuildContext context, List<DocumentSnapshot> snapshot) {
        return ListView(
          padding: const EdgeInsets.only(top: 20.0),
          children: snapshot.map((data) => _buildListItem(context, data)).toList(),
        );
      }

      Widget _buildListItem(BuildContext context, DocumentSnapshot data) {
        final record = Record.fromSnapshot(data);

        return Padding(
          key: ValueKey(record.name),
          padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
          child: Container(
            decoration: BoxDecoration(
              border: Border.all(color: Colors.grey),
              borderRadius: BorderRadius.circular(5.0),
            ),
            child: DataTable(
              columns: [
                DataColumn(label: Text('Name')),
                DataColumn(label: Text('Votes')),
                DataColumn(label: Text('Rapper\nname')),
              ],
              rows: [
                DataRow(cells: [
                  DataCell(Text(record.name)),
                  DataCell(Text(record.votes.toString())),
                  DataCell(Text(record.rName)),
                ])
              ],
            ),
          ),
        );
      }
    }

【问题讨论】:

    标签: firebase flutter dart datatables google-cloud-firestore


    【解决方案1】:

    从您的代码中可以看出,很明显您正在返回全新的 DataTable,因此您每次都会获取列名。

    您必须在 _buildBody 方法中创建 Datatable,然后从 _buildListItem 方法返回 DataRow 列表。

    我希望以下代码对您有用。由于没有正确的设置,我没有测试下面的代码。如果您再次遇到任何问题,请添加评论。

    Widget _buildBody(BuildContext context) {
        return StreamBuilder<QuerySnapshot>(
          stream: Firestore.instance.collection('baby').snapshots(),
          builder: (context, snapshot) {
            if (!snapshot.hasData) return LinearProgressIndicator();
    
            return DataTable(
              columns: [
                DataColumn(label: Text('Name')),
                DataColumn(label: Text('Votes')),
                DataColumn(label: Text('Rapper\nname')),
              ],
              rows: _buildList(context, snapshot.data.documents)
            );
          },
        );
      }
    
    
    
    
        List<DataRow> _buildList(BuildContext context, List<DocumentSnapshot> snapshot) {
            return  snapshot.map((data) => _buildListItem(context, data)).toList();
        }
    
    
    
     DataRow _buildListItem(BuildContext context, DocumentSnapshot data) {
        final record = Record.fromSnapshot(data);
    
        return DataRow(cells: [
                  DataCell(Text(record.name)),
                  DataCell(Text(record.votes.toString())),
                  DataCell(Text(record.rName)),
                ]);
      }
    

    【讨论】:

    • 感谢您的回答!当我关注它时,我收到了几个错误。任何建议都会受到欢迎!例如。 Record.fromSnapshot(DocumentSnapshot snapshot); : this.fromMap(snapshot.data, reference: snapshot.reference); 收到一条错误消息,指出 'fromMap' 必须有方法体,因为 'Record' 不是抽象的。同样,代码], rows: _buildList(context, snapshot.data.documents)); 得到错误参数类型'Widget'不能分配给参数类型'List'。
    • @BenoitCerise 您可以编辑我的答案。我知道我也需要更改返回数据类型,所以如果您可以更改,请更改它。
    【解决方案2】:
    Widget build(BuildContext context) {
        final products = Provider.of<List<Product>>(context);
        return Scaffold(
            body: Container(
              child: DataTable(
                columns: [
                  DataColumn(label: Text('Id')),
                  DataColumn(label: Text('Name')),
                  DataColumn(label: Text('Price')),
                ],
                rows: List<DataRow>.generate(
                    products.length,
                    (index) => DataRow(cells: [
                          DataCell(Text(products[index].productId)),
                          DataCell(Text(products[index].name)),
                          DataCell(Text(products[index].price.toString())),
                        ])),
              ),
            ),
    
    
      Stream<List<Product>> getProducts(){
        return _db.collection('products').snapshots().map((snapshot) => snapshot.docs.map((document) => Product.fromFirestore(document.data())).toList());
      }
    
    

    我使用provider来管理我的状态,希望能帮到你

    【讨论】:

    • 你能告诉我在产品的 fromFirestore() 中写什么吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-31
    • 2020-07-21
    • 2020-09-29
    • 2021-06-03
    • 2021-01-06
    • 2021-03-19
    • 1970-01-01
    相关资源
    最近更新 更多