在ExpansionPanelList中使用提供程序

时间:2020-10-30 20:35:29

标签: android flutter dart provider

我正在尝试将提供程序与ExpansionPanelList一起使用。 问题在于,我需要为每个ExpansionPanel提供一个新的provider实例,但ExpansionPanelList需要expandCallBack函数,该函数控制扩展(bool isExpanded)的状态。

这是使用setState和StatefulWidget的示例代码,我正在尝试将其移植到提供程序。

class ExpansionPanelProvider {
  ExpansionPanelProvider({
    this.expandedValue,
    this.headerValue,
    this.isExpanded = false,
  });

  String expandedValue;
  String headerValue;
  bool isExpanded;

  /*void updateExpansionState() {
      isExpanded = !isExpanded;
      notifyListeners();
  }*/

}

List<ExpansionPanelProvider> generateItems(int numberOfItems) {
  return List.generate(numberOfItems, (int index) {
    return ExpansionPanelProvider(
      headerValue: 'Panel ${index + 1}',
      expandedValue: 'This is item number ${index + 1}',
    );
  });
}

/// This is the stateful widget that the main application instantiates.
class MyStatefulWidget extends StatefulWidget {
  MyStatefulWidget({Key key}) : super(key: key);
  @override
  _MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}

/// This is the private State class that goes with MyStatefulWidget.
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
  List<ExpansionPanelProvider> _data = generateItems(80);
  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      child: Container(
        child: _buildPanel(),
      ),
    );
  }

  Widget _buildPanel() {
    return ExpansionPanelList(
      animationDuration: Duration(milliseconds: 800),
      expansionCallback: (int index, bool isExpanded) {
        setState(() {
          _data[index].isExpanded = !isExpanded;
        });
      },
      children: _data.map<ExpansionPanel>((ExpansionPanelProvider item) {
        return ExpansionPanel(
          canTapOnHeader: true,
          isExpanded: item.isExpanded,
          headerBuilder: (BuildContext context, bool isExpanded) {
            return ListTile(
              title: Text(item.headerValue),
            );
          },
          body: ListTile(
              title: Text(item.expandedValue),
              subtitle: Text('To delete this panel, tap the trash can icon'),
              trailing: Icon(Icons.delete),
              onTap: () {
                setState(() {
                  _data.removeWhere((currentItem) => item == currentItem);
                });
              }),
        );
      }).toList(),
    );
  }
}

此代码使用设置的字符串和要显示的数据。我的数据来自其他提供商。

[编辑]

我曾尝试将ExpansionPanel封装在ChangeNotifierProvider中,但这没有用,因为ExpansionPanel只能是ExpansionPanelList窗口小部件的子代。

1 个答案:

答案 0 :(得分:0)

虽然我们对差异进行了编码,但我遇到了与您相同的问题。 我通过将 extends ChangeNotifier 添加到 ExpansionPanelItem 类解决了这个问题。 Like which did as Flutter documentation,迭代 panel-item-class 并在 ChangeNotifierProvider.value(...) 中的 headerBuliderbody 属性周围包裹一个 ExpansionPanel

ExpansionPanel(
      canTapOnHeader: true,
      headerBuilder: (ctx, bool) => ChangeNotifierProvider.value(
        value: item,
        child: _buildPanelHeader(item, index),
      ),
      body: ChangeNotifierProvider.value(
        value: item,
        child: item.body,
      ),
      isExpanded: item.isExpanded,
    )

然后将 Consumer 包裹在您构建正文和标题的位置,如下所示:

// ...
Widget _buildPanelHeader(ExpansionPanelItem item, int index) {
return Consumer<ExpansionPanelItem>(
  builder: (ctx, itemRef, c) {
    return Container(
      // your header
    );
  }
);

}