📜  Flutter – 扩展面板(1)

📅  最后修改于: 2023-12-03 15:30:49.277000             🧑  作者: Mango

Flutter – 扩展面板

在 Flutter 中,扩展面板是一个常用的 UI 元素,它可以用来展示和隐藏内容。扩展面板通常会有一个标题和一个展开或收缩的按钮,当点击展开或收缩按钮时,扩展面板会显示或隐藏内容。

创建扩展面板

要创建一个扩展面板,我们可以使用 ExpansionPanelListExpansionPanel 这两个类。ExpansionPanelList 通常存放一组 ExpansionPanel,每个 ExpansionPanel 有自己的标题和内容。下面是一个简单的创建扩展面板的例子:

class MyPanel extends StatefulWidget {
  @override
  _MyPanelState createState() => _MyPanelState();
}

class _MyPanelState extends State<MyPanel> {
  List<bool> _isOpenList = [false, false, false];

  final List<ExpansionPanel> _panels = [
    ExpansionPanel(
      headerBuilder: (BuildContext context, bool isExpanded) {
        return ListTile(
          title: Text('Panel 1'),
        );
      },
      body: Container(
        padding: EdgeInsets.all(16.0),
        child: Text('Content of Panel 1'),
      ),
      isExpanded: false,
    ),
    ExpansionPanel(
      headerBuilder: (BuildContext context, bool isExpanded) {
        return ListTile(
          title: Text('Panel 2'),
        );
      },
      body: Container(
        padding: EdgeInsets.all(16.0),
        child: Text('Content of Panel 2'),
      ),
      isExpanded: false,
    ),
    ExpansionPanel(
      headerBuilder: (BuildContext context, bool isExpanded) {
        return ListTile(
          title: Text('Panel 3'),
        );
      },
      body: Container(
        padding: EdgeInsets.all(16.0),
        child: Text('Content of Panel 3'),
      ),
      isExpanded: false,
    ),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('My Panel'),
      ),
      body: SingleChildScrollView(
        child: ExpansionPanelList(
          expansionCallback: (int index, bool isOpen) {
            setState(() => _isOpenList[index] = !isOpen);
          },
          children: _panels.map((ExpansionPanel panel) {
            return ExpansionPanel(
              headerBuilder: panel.headerBuilder,
              body: panel.body,
              isExpanded: _isOpenList[_panels.indexOf(panel)],
            );
          }).toList(),
        ),
      ),
    );
  }
}
修改扩展面板的样式

我们可以通过 ExpansionPanelListThemeExpansionPanelTheme 来修改扩展面板的样式。ExpansionPanelListTheme 可以修改整个 ExpansionPanelList 的样式,而 ExpansionPanelTheme 可以修改单个 ExpansionPanel 的样式。

下面是一个修改扩展面板样式的例子:

class MyThemePanel extends StatefulWidget {
  @override
  _MyThemePanelState createState() => _MyThemePanelState();
}

class _MyThemePanelState extends State<MyThemePanel> {
  List<bool> _isOpenList = [false, false, false];

  final List<ExpansionPanel> _panels = [
    ExpansionPanel(
      headerBuilder: (BuildContext context, bool isExpanded) {
        return ListTile(
          title: Text('Panel 1'),
        );
      },
      body: Container(
        padding: EdgeInsets.all(16.0),
        child: Text('Content of Panel 1'),
      ),
      isExpanded: false,
    ),
    ExpansionPanel(
      headerBuilder: (BuildContext context, bool isExpanded) {
        return ListTile(
          title: Text('Panel 2'),
        );
      },
      body: Container(
        padding: EdgeInsets.all(16.0),
        child: Text('Content of Panel 2'),
      ),
      isExpanded: false,
    ),
    ExpansionPanel(
      headerBuilder: (BuildContext context, bool isExpanded) {
        return ListTile(
          title: Text('Panel 3'),
        );
      },
      body: Container(
        padding: EdgeInsets.all(16.0),
        child: Text('Content of Panel 3'),
      ),
      isExpanded: false,
    ),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('My Theme Panel'),
      ),
      body: SingleChildScrollView(
        child: Theme(
          data: ThemeData(
            accentColor: Colors.red,
            dividerColor: Colors.blue,
            unselectedWidgetColor: Colors.green,
            textTheme: TextTheme(
              bodyText1: TextStyle(color: Colors.yellow),
              bodyText2: TextStyle(color: Colors.orange),
            ),
          ),
          child: ExpansionPanelListTheme(
            data: ExpansionPanelListThemeData(
              dividerColor: Colors.purple,
              iconColor: Colors.blue,
              expandedHeaderPadding: EdgeInsets.all(16.0),
              animationDuration: Duration(milliseconds: 2000),
            ),
            child: ExpansionPanelTheme(
              data: ExpansionPanelThemeData(
                headerPadding: EdgeInsets.all(16.0),
                iconColor: Colors.yellow,
                iconSize: 24.0,
                isExpanded: true,
                canTapOnHeader: false,
                tapHeaderToExpand: true,
                tapBodyToCollapse: false,
                bodyAlignment: Alignment.centerLeft,
                bodyColor: Colors.grey,
                bodyPadding: EdgeInsets.all(16.0),
                borderRadius: BorderRadius.circular(16.0),
              ),
              child: ExpansionPanelList(
                expansionCallback: (int index, bool isOpen) {
                  setState(() => _isOpenList[index] = !isOpen);
                },
                children: _panels.map((ExpansionPanel panel) {
                  return ExpansionPanel(
                    headerBuilder: panel.headerBuilder,
                    body: panel.body,
                    isExpanded: _isOpenList[_panels.indexOf(panel)],
                  );
                }).toList(),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

以上就是 Flutter 中扩展面板的基本使用及样式修改方法。