Flutter 转换 - UICollectionViewDiffableDataSource

Flutter Conversion - UICollectionViewDiffableDataSource

我正在尝试将我现有的 iOS 应用程序转换为 Flutter。

在 iOS 中,我正在使用 UICollectionViewDiffableDataSource 查看这样的结构:

struct ClassItem: Hashable{
 let year: String
 let students: [StudentItem]
}

let BiologyClass = [
 ClassItem(year: "2021", students: [
  StudentItem(name: "Michael Pearson", favColor: "blue"),
  StudentItem(name: "Pearson Michael", favColor: "green")
 ]),
 ClassItem(year: "2020", students: [
  StudentItem(name: "Steve Pearson", favColor: "blue"),
  StudentItem(name: "Steve Michael", favColor: "green"),
  StudentItem(name: "Pearson Steve", favColor: "red")
 ]),

看起来像这样:

iosView

在 Flutter 中,我尝试使用 ExpansionPanel:

  Widget build(BuildContext context) {
    return ExpansionPanelList(
            children: [
              ExpansionPanel(
                headerBuilder: (context, isExpanded) {
                  return ListTile(
                    title: Text(
                      '2021',
                      style: TextStyle(color: Colors.black),
                    ),
                  );
                },
                body: Column(
                  children: [
                    ListTile(
                      title: Text('Description text',
                          style: TextStyle(color: Colors.black)),
                    ),
                    ListTile(
                      title: Text('Description text2',
                          style: TextStyle(color: Colors.black)),
                    ),
                  ],
                ),
                isExpanded: _expanded,
                canTapOnHeader: true,
              ),
            ],
            dividerColor: Colors.grey,
            expansionCallback: (panelIndex, isExpanded) {
              _expanded = !_expanded;
              setState(() {});
            },
      
    ); 

所以问题是,如何在 ExpansionPanel 中创建可变数量的图块。或者更好的是,如何构建像在 iOS env 中使用 UICollectionViewDiffableDataSource 所示的内容。目前我必须手动创建所有图块,而这在最终版本中是不可行的。 Flutter 目前看起来像这样:

FlutterView

谢谢。

编辑: 出现错误“找到重复键”。 下图显示了调试 window。 我不知道为什么条目要加倍。

EDIT2:知道了,在 CustomExpansionTile 中注释掉了一行!

输出:

创建类似于 Swift 结构的数据模型和数据源作为 BiologyClass:

class ClassItem {
  ClassItem({this.isExpanded: false, this.year, this.students});

  bool isExpanded;
  final String year;
  final List<StudentItem> students;
}

class StudentItem {
  StudentItem({this.name, this.favColor});

  final String name;
  final String favColor;
}

现在您可以遍历项目并使用动态数据填充 ExpansionPanelList:

class _MyHomePageState extends State<MyHomePage> {
  List<ClassItem> _items = <ClassItem>[
    ClassItem(year: "2021", students: [
      StudentItem(favColor: "blue", name: "Michael Pearson"),
      StudentItem(favColor: "green", name: "Pearson Michael")
    ]),
    ClassItem(year: "2020", students: [
      StudentItem(favColor: "blue", name: "Steve Pearson"),
      StudentItem(favColor: "green", name: "Steve Michael"),
      StudentItem(favColor: "red", name: "Pearson Steve")
    ]),
  ];

  @override
  Widget build(BuildContext context) {
    return ListView(
      children: <Widget>[
        ExpansionPanelList(
          expansionCallback: (int index, bool isExpanded) {
            setState(() {
              _items[index].isExpanded = !_items[index].isExpanded;
            });
          },
          children: _items.map((ClassItem item) {
            return ExpansionPanel(
              headerBuilder: (BuildContext context, bool isExpanded) {
                return Text(item.year);
              },
              isExpanded: item.isExpanded,
              body: Column(children: [
                ...item.students.map((StudentItem student) {
                  return GestureDetector(
                    onTap: () {
                      print(student.name);
                    },
                    child: Container(child: Padding(padding: const EdgeInsets.all(8.0), child: Text(student.name))),
                  );
                }).toList(),
              ]),
            );
          }).toList(),
        )
      ],
    );
  }
}