美文网首页
Flutter 组件之 ExpansionPanel、Expan

Flutter 组件之 ExpansionPanel、Expan

作者: maskerII | 来源:发表于2022-05-19 21:02 被阅读0次

ExpansionPanel、ExpansionPanelRadio 是一种常见的折叠框。
ExpansionPanelList 是承载折叠框的一个父类控件。

1. ExpansionPanel

ExpansionPanel 定义

  ExpansionPanel({
    required this.headerBuilder,
    required this.body,
    this.isExpanded = false,
    this.canTapOnHeader = false,
    this.backgroundColor,
  })

ExpansionPanel 属性

ExpansionPanel 属性 介绍
headerBuilder @required,Header Widget 构造方法
body @required,展开部分 Widget
isExpanded 是否展开,默认为 false
canTapOnHeader 点击 header 是否可以展开收起,false
backgroundColor 背景色

2. ExpansionPanelRadio

ExpansionPanelRadio 定义

  ExpansionPanelRadio({
    required this.value,
    required ExpansionPanelHeaderBuilder headerBuilder,
    required Widget body,
    bool canTapOnHeader = false,
    Color? backgroundColor,
  })

ExpansionPanelRadio属性

ExpansionPanelRadio属性 介绍
value @required 唯一标识
headerBuilder @required Header Widget 构造方法
body @required,展开部分 Widget
canTapOnHeader 是否可以点击 header 用来展开收起,false
backgroundColor 背景色

3. ExpansionPanelList

3.1 ExpansionPanelList 默认构造函数

ExpansionPanelList 定义

  const ExpansionPanelList({
    Key? key,
    this.children = const <ExpansionPanel>[],
    this.expansionCallback,
    this.animationDuration = kThemeAnimationDuration,
    this.expandedHeaderPadding = _kPanelHeaderExpandedDefaultPadding,
    this.dividerColor,
    this.elevation = 2,
  }) 

ExpansionPanelList属性

ExpansionPanelList属性 介绍
children 子控件数组,List<ExpansionPanel>
expansionCallback 展开收起回调函数,(index, isExpand){},返回当前下标以及是否折叠
animationDuration 动画时间,默认为 kThemeAnimationDuration
expandedHeaderPadding 展开后 Header 的 padding,默认为 _kPanelHeaderExpandedDefaultPadding
dividerColor 分割线颜色
elevation 阴影大小 不可以随意设置,具体看kElevationToShadow

3.2 ExpansionPanelList.radio

ExpansionPanelList.radio 定义

  const ExpansionPanelList.radio({
    Key? key,
    this.children = const <ExpansionPanelRadio>[],
    this.expansionCallback,
    this.animationDuration = kThemeAnimationDuration,
    this.initialOpenPanelValue,
    this.expandedHeaderPadding = _kPanelHeaderExpandedDefaultPadding,
    this.dividerColor,
    this.elevation = 2,
  })

ExpansionPanelList.radio属性

ExpansionPanelList.radio属性 介绍
children 子控件数组,List< ExpansionPanelRadio >
expansionCallback 展开收起回调函数,(index, isExpand){},返回当前下标以及是否折叠
animationDuration 动画时间,默认为 kThemeAnimationDuration
initialOpenPanelValue 默认打开的ExpansionPanelRadio的标识
expandedHeaderPadding 展开后 Header 的 padding,默认为 _kPanelHeaderExpandedDefaultPadding
dividerColor 分割线颜色
elevation 阴影大小 不可以随意设置,具体看kElevationToShadow

ExpansionPanelList.radio 对比ExpansionPanelList 默认构造函数,只增加了一个initialOpenPanelValue 属性

4. ExpansionPanelList 实例

示例1 ExpansionPanelList


class MSExpansionPanelListDemo extends StatefulWidget {
  const MSExpansionPanelListDemo({Key? key}) : super(key: key);

  @override
  State<MSExpansionPanelListDemo> createState() =>
      _MSExpansionPanelListDemoState();
}

class _MSExpansionPanelListDemoState extends State<MSExpansionPanelListDemo> {
  List<MSExpansionPanelModel> _models = [];
  @override
  void initState() {
    _models.add(MSExpansionPanelModel("EP1", "Title EP1", false));
    _models.add(MSExpansionPanelModel("EP2", "Title EP2", false));
    _models.add(MSExpansionPanelModel("EP3", "Title EP3", false));
    _models.add(MSExpansionPanelModel("EP4", "Title EP4", false));
    _models.add(MSExpansionPanelModel("EP5", "Title EP5", false));
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("ExpansionPanelListDemo")),
      body: SingleChildScrollView(
        child: _expansionPanelList(),
      ),
    );
  }

  List<ExpansionPanel> _initChildrenForExpansionPanel() {
    List<ExpansionPanel> _childrenForExpansionPanel = [];
    _models.forEach((element) {
      _childrenForExpansionPanel.add(_expansionPanelForModel(element));
    });
    return _childrenForExpansionPanel;
  }

  // 创建 ExpansionPanel
  ExpansionPanel _expansionPanelForModel(MSExpansionPanelModel model) {
    return ExpansionPanel(
      // header 构造函数
      headerBuilder: (context, isExpanded) {
        return Container(
          height: 56,
          alignment: Alignment.centerLeft,
          child: Text(model.title),
        );
      },
      // body 展开部分 Widget
      body: Container(
        height: 100,
        color: Colors.red,
      ),
      // 是否展开
      isExpanded: model.isExpanded,
      // 点击 header 是否可以展开收起,false
      canTapOnHeader: true,
      // 背景色
      backgroundColor: Colors.cyan[100],
    );
  }

  // 创建 ExpansionPanelList
  ExpansionPanelList _expansionPanelList() {
    return ExpansionPanelList(
      // 子控件数组 List<ExpansionPanel>
      children: _initChildrenForExpansionPanel(),
      // 分割线
      dividerColor: Colors.green,
      //动画时间,默认为 kThemeAnimationDuration
      animationDuration: Duration(milliseconds: 200),
      // 展开后 Header 的 padding,默认为 _kPanelHeaderExpandedDefaultPadding
      expandedHeaderPadding: EdgeInsets.all(8),
      // 展开收起回调函数,(index, isExpand){},返回当前下标以及是否折叠
      expansionCallback: (index, isExpand) {
        _models[index].isExpanded = !isExpand;
        setState(() {});
      },
      // 阴影大小
      elevation: 6,
    );
  }
}

class MSExpansionPanelModel {
  var value;
  String title;
  bool isExpanded;
  MSExpansionPanelModel(this.value, this.title, this.isExpanded);
}
129.gif

示例2 ExpansionPanelList.radio


class MSExpansionPanelListDemo2 extends StatefulWidget {
  const MSExpansionPanelListDemo2({Key? key}) : super(key: key);

  @override
  State<MSExpansionPanelListDemo2> createState() =>
      _MSExpansionPanelListDemo2State();
}

class _MSExpansionPanelListDemo2State extends State<MSExpansionPanelListDemo2> {
  List<MSExpansionPanelModel> _models = [];
  @override
  void initState() {
    _models.add(MSExpansionPanelModel("EP1", "Title EP1", false));
    _models.add(MSExpansionPanelModel("EP2", "Title EP2", false));
    _models.add(MSExpansionPanelModel("EP3", "Title EP3", false));
    _models.add(MSExpansionPanelModel("EP4", "Title EP4", false));
    _models.add(MSExpansionPanelModel("EP5", "Title EP5", false));
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("ExpansionPanelListDemo2")),
      body: SingleChildScrollView(
        child: _expansionPanelListForRadio(),
      ),
    );
  }

  List<ExpansionPanelRadio> _initChildrenForExpansionPanelRadio() {
    List<ExpansionPanelRadio> _childrenForExpansionPanelRadio = [];
    _models.forEach((element) {
      _childrenForExpansionPanelRadio
          .add(_expansionPanelRadioForModle(element));
    });
    return _childrenForExpansionPanelRadio;
  }

  ExpansionPanelRadio _expansionPanelRadioForModle(
      MSExpansionPanelModel model) {
    return ExpansionPanelRadio(
      // 唯一标识
      value: model.value,
      // Header Widget 构造方法
      headerBuilder: (context, isExpanded) {
        return Container(
          height: 56,
          alignment: Alignment.centerLeft,
          child: Text(model.title),
        );
      },
      // 展开部分 Widget
      body: Container(
        height: 100,
        color: Colors.red,
      ),
      // 是否可以点击 header 用来展开收起,false
      canTapOnHeader: true,
      // 背景色
      backgroundColor: Colors.blue[100],
    );
  }

  ExpansionPanelList _expansionPanelListForRadio() {
    return ExpansionPanelList.radio(
      // 子控件数组,List< ExpansionPanelRadio >
      children: _initChildrenForExpansionPanelRadio(),
      // 展开后 Header 的 padding,默认为 _kPanelHeaderExpandedDefaultPadding
      expandedHeaderPadding: EdgeInsets.all(8),
      // 展开收起回调函数,(index, isExpand){},返回当前下标以及是否折叠
      expansionCallback: (index, isExpand) {
        print("expansionCallback index $index, isExpand $isExpand");
      },
      // 默认打开的ExpansionPanelRadio的标识
      initialOpenPanelValue: "EP2",
      // 动画时间,默认为 kThemeAnimationDuration
      animationDuration: Duration(milliseconds: 200),
      // 分割线颜色
      dividerColor: Colors.purple,
      // 阴影大小 不可以随意设置,具体看kElevationToShadow
      elevation: 6,
    );
  }
}

class MSExpansionPanelModel {
  var value;
  String title;
  bool isExpanded;
  MSExpansionPanelModel(this.value, this.title, this.isExpanded);
}

130.gif

ExpansionPanelList.radio 仅可以展开一个 ExpansionPanel,ExpansionPanelList 默认构造函数可以展开多个

5. 总结

  • 注意 ExpansionPanel 不可以直接作为子控件给到 body,否则会报错,这里用了 SingleChildScrollView 作为外层容器,使用 Column、ListView...等很多控件都可以。
  • 注意使用 ExpansionPanelList() 与 ExpansionPanelList.radio() 创建出来的 Widget,他们的 children 分别对应 <ExpansionPanel>,<ExpansionPanelRadio>,此处容易报错。
  • 注意 ExpansionPanelRadio.value 不可以相同,容易报错。

相关文章

网友评论

      本文标题:Flutter 组件之 ExpansionPanel、Expan

      本文链接:https://www.haomeiwen.com/subject/gkqxprtx.html