dart - 来自Json的Flutter Dart Sticky Header

标签 dart flutter

我试图从json创建 flutter 的粘性 header 列表。我发现很难从json按日期进行分组,我想了解更多有关如何操纵列表和 map 的信息。如果有 body 可以帮助的话。

[
  {
    "_id": "5bbe598c20a312e8f3a51692",
    "index": 0,
    "guid": "853882bb-5432-4efa-9886-38491397cb22",
    "isActive": false,
    "balance": "$3,493.46",
    "picture": "http://placehold.it/32x32",
    "age": 22,
    "eyeColor": "green",
    "name": {
      "first": "Maryellen",
      "last": "Moody"
    },
    "company": "SURETECH",
    "registered": "Fri Jul 21 1995 05:54:11 GMT+0000 (UTC)"
  },
  {
    "_id": "5bbe598c325e76f346816167",
    "index": 1,
    "guid": "672ac480-f8fc-47e8-a960-bac230f11dab",
    "isActive": true,
    "balance": "$3,081.07",
    "picture": "http://placehold.it/32x32",
    "age": 39,
    "eyeColor": "green",
    "name": {
      "first": "Duffy",
      "last": "Knight"
    },
    "company": "CYCLONICA",
    "registered": "Fri Jul 21 1995 09:54:11 GMT+0000 (UTC)"
  },
  {
    "_id": "5bbe598c0ce158b98ebafcf2",
    "index": 2,
    "guid": "4528d59a-2eb1-4726-ae4b-5cc8d9495d5e",
    "isActive": true,
    "balance": "$2,588.97",
    "picture": "http://placehold.it/32x32",
    "age": 29,
    "eyeColor": "brown",
    "name": {
      "first": "Traci",
      "last": "Grimes"
    },
    "company": "DOGNOST",
    "registered": "Sun Jul 31 2011 03:25:47 GMT+0000 (UTC)"
  },
  {
    "_id": "5bbe598cc666e2e9561ad82e",
    "index": 3,
    "guid": "085883af-3ad4-4779-ac4d-5c5374d81144",
    "isActive": true,
    "balance": "$3,928.99",
    "picture": "http://placehold.it/32x32",
    "age": 26,
    "eyeColor": "brown",
    "name": {
      "first": "Reyna",
      "last": "Bond"
    },
    "company": "MOREGANIC",
    "registered": "Sun Jul 31 2011 06:25:47 GMT+0000 (UTC)"
  }
]

我正在尝试获取同一日期的记录并将其与粘性 header 分组

1995年7月21日星期五-粘性 header

3,493.46美元-Maryellen
$ 3,081.07-Duffy

2011年7月31日,星期日

$ 2,588.97-Traci
$ 3,928.99-雷娜

我试图隐含的软件包
https://pub.dartlang.org/packages/sticky_header_list
https://pub.dartlang.org/packages/sticky_headers

我是新来的 flutter 。但是我爱上了它。试图理解逻辑

最佳答案

脚步:

  • 加载json并转换为数据对象
  • 按日期分组数据对象
  • 将组数据转换为 View

  • 检查以下代码,它应能按预期工作。
    // main.dart
    import 'dart:convert';
    
    import 'package:flutter/material.dart';
    import 'package:intl/intl.dart';
    import 'package:flutter/services.dart' show rootBundle;
    import 'package:sticky_headers/sticky_headers.dart';
    
    void main() => runApp(new MyApp());
    
    class MyApp extends StatelessWidget {
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return new MaterialApp(
          title: 'Flutter Demo',
          theme: new ThemeData(
            // This is the theme of your application.
            //
            // Try running your application with "flutter run". You'll see the
            // application has a blue toolbar. Then, without quitting the app, try
            // changing the primarySwatch below to Colors.green and then invoke
            // "hot reload" (press "r" in the console where you ran "flutter run",
            // or press Run > Flutter Hot Reload in IntelliJ). Notice that the
            // counter didn't reset back to zero; the application is not restarted.
            primarySwatch: Colors.blue,
          ),
          home: CompanyPage(title: "Company Page")
        );
      }
    }
    
    class Name {
      final String first;
      final String last;
      Name({this.first, this.last});
    
      Name.fromJson(Map<String, dynamic> json)
          : first = json['first'],
            last = json['last'];
    }
    
    class Company {
      final String id;
      final int index;
      final String guid;
      final bool isActive;
      final String balance;
      final String picture;
      final int age;
      final String eyeColor;
      final Name name;
      final String company;
      final DateTime registered;
    
      Company({
        this.id, this.index, this.guid, this.isActive,
        this.balance, this.picture, this.age, this.eyeColor,
        this.name, this.company, this.registered
      });
    
      Company.fromJson(Map<String, dynamic> json)
          : id          = json['_id'],
            index       = json['index'],
            guid        = json['guid'],
            isActive    = json['isActive'],
            balance     = json['balance'],
            picture     = json['picture'],
            age         = json['age'],
            eyeColor    = json['eyeColor'],
            name        = Name.fromJson(json['name']),
            company     = json['company'],
            registered  = _toDateTime(json['registered']);
    
      /// Fri Jul 21 1995 05:54:11 GMT+0000 (UTC)
      static DateTime _toDateTime(String dateTime) {
        return DateFormat("EEE MMM d yyyy HH:mm:ss").parseUtc(dateTime);
      }
    }
    
    class CompanyViewInfo {
      final Widget header;
      final Widget child;
      CompanyViewInfo({this.header, this.child});
    }
    
    class CompanyPage extends StatefulWidget {
      final String title;
      CompanyPage({Key key, this.title}) : super(key: key);
    
      @override
      State<StatefulWidget> createState() => _CompanyPageState();
    }
    
    class _CompanyPageState extends State<CompanyPage> {
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(title: Text(widget.title)),
            body: FutureBuilder(
                future: _getCompanyList(),
                builder: (context, snapshot) {
                  if(snapshot.hasError) print(snapshot.error);
                  if (snapshot.data == null) return Center(child: CircularProgressIndicator());
    
                  final groupList = _groupByDate(snapshot.data);
                  return ListView.builder(
                    itemBuilder: (context, index) =>
                        StickyHeader(
                            header: groupList[index].header,
                            content: groupList[index].child
                        ),
                    itemCount: groupList.length,
                  );
                })
        );
      }
    }
    
    Future<List<Company>> _getCompanyList() async {
      final jsonString = await rootBundle.loadString("assets/companies.json");
      return List.castFrom(json.decode(jsonString)).map((c) => Company.fromJson(c)).toList();
    }
    
    List<CompanyViewInfo> _groupByDate(List<Company> companyList) {
      final map = groupBy(
          keySelector: (Company c) => DateFormat("EEE MM d yyyy").format(c.registered),
          list: companyList
      );
    
      return toList(
          mapF: (String date, List<Company> list) {
            final header = Container(
              height: 50.0,
              color: Colors.blue[700],
              padding: EdgeInsets.symmetric(horizontal: 16.0),
              alignment: Alignment.centerLeft,
              child: Text(date, style: TextStyle(color: Colors.white)),
            );
    
            final child = Text(list.map((c) => "${c.balance} - ${c.name.first}").join(" "));
    
            return CompanyViewInfo(header: header, child: child);
          },
          map: map
      );
    }
    
    Map<K, List<T>> groupBy<T, K>({K Function(T) keySelector, List<T> list}) {
      Map<K, List<T>> destination = Map();
    
      for (T element in list) {
        final key = keySelector(element);
        final value = destination[key] ?? List();
        value.add(element);
        destination[key] = value;
      }
    
      return destination;
    }
    
    List<R> toList<K, V, R>({R Function(K, V) mapF, Map<K, V> map}) {
      List<R> destination = List();
      map.forEach((k, v) => destination.add(mapF(k, v)));
      return destination;
    }
    

    pubspec.yaml
    dependencies:
      flutter:
        sdk: flutter
      intl: ^0.15.7
      sticky_headers: "^0.1.7"
    
    assets:
      - assets/companies.json
    

    记得把companies.json放在your_project_root/assets/companies.json

    关于dart - 来自Json的Flutter Dart Sticky Header,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52748152/

    相关文章:

    android - 在 Release模式下检查互联网连接不起作用

    flutter - 在build-Method中分配InheritedWidget

    flutter - 使用JsonPlaceHolder时出现错误: The argument type 'String' can't be assigned to the parameter type 'Uri' .

    firebase - Android 上的 Flutter/Firebase verifyPhoneNumber() 总是调用 recaptcha "Verifying you' re not a robots"

    android - flutter 应用在​​后台时调用 onMessage 方法

    flutter - 无法启动 Dart CLI 隔离(空)。在苹果电脑中

    dart - 为什么 `final var` 在 Dart 中是非法的?

    flutter - Dart :将 map 转换为2个列表

    dart - Flutter:实现 Material Search 栏以从服务器异步搜索数据

    flutter - 我怎样才能将扁平按钮的大小设置为 child 的大小