【问题标题】:Using Provider in ExpansionPanelList在 ExpansionPanelList 中使用 Provider
【发布时间】:2021-02-13 07:58:57
【问题描述】:

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

这是使用 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 Widget 的子级。

【问题讨论】:

  • 与其创建提供者列表,不如在提供者中为 ExpansionPanel 创建一个项目列表,并设置您的 ExpansionPanel 监听此项目列表?

标签: android flutter dart provider


【解决方案1】:

尽管我们对差异进行了编码,但我遇到了与您相同的问题。 我通过将 extends ChangeNotifier 添加到 ExpansionPanelItem 类解决了这个问题。 Like which did as Flutter documentation,迭代面板项类并在ExpansionPanel 中围绕headerBuliderbody 属性包装ChangeNotifierProvider.value(...)

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
    );
  }
);

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-19
    • 1970-01-01
    • 1970-01-01
    • 2021-06-07
    • 1970-01-01
    • 2020-03-13
    • 1970-01-01
    • 2020-01-06
    相关资源
    最近更新 更多