zoukankan      html  css  js  c++  java
  • Flutter 系统是如何实现ExpansionPanelList的

    老孟导读:Flutter组件有一个很大的特色,那就是很多复杂的组件都是通过一个一个小组件拼装而成的,今天就来说说系统的ExpansionPanelList是如何实现的。

    在了解ExpansionPanelList实现前,先来了解下MergeableMaterial,它展示多个MergeableMaterialItem组件,当子组件发生变化时,以动画的方式打开或者关闭子组件,MergeableMaterial的父控件需要在主轴方向是一个没有限制的控件,比如SingleChildScrollView、Row、Column等。

    基本用法如下:

    SingleChildScrollView(
      child: MergeableMaterial(
        children: [
          MaterialSlice(
              key: ValueKey(1),
              child: Container(
                height: 45,
                color: Colors.primaries[1 % Colors.primaries.length],
              )),
          MaterialGap(key: ValueKey(2)),
          MaterialSlice(
              key: ValueKey(3),
              child: Container(
                height: 45,
                color: Colors.primaries[1 % Colors.primaries.length],
              )),
          MaterialGap(key: ValueKey(4)),
          MaterialSlice(
              key: ValueKey(5),
              child: Container(
                height: 45,
                color: Colors.primaries[1 % Colors.primaries.length],
              )),
        ],
      ),
    )
    

    效果如下:

    MergeableMaterial的子控件只能是MaterialSlice和MaterialGap,MaterialSlice是带子控件的控件,显示实际内容,MaterialGap用于分割,只能放在MaterialSlice中间。

    静态情况下,看不出具体的效果,动态改变子组件用法如下:

    List<MergeableMaterialItem> items = [];
    List.generate(_count, (index) {
      items.add(MaterialSlice(
          key: ValueKey(index * 2),
          child: Container(
            height: 45,
            color: Colors.primaries[index % Colors.primaries.length],
          )));
    });
    
    return SingleChildScrollView(
      child: MergeableMaterial(
        children: items,
      ),
    )
    

    效果如下:

    主要看增加/删除子组件时的动画效果。

    增加分割线和阴影:

    MergeableMaterial(
      hasDividers: true,
      elevation: 24,
      children: items,
    )
    

    效果如下:

    阴影值不能随便设置,只能设置如下值:1, 2, 3, 4, 6, 8, 9, 12, 16, 24

    此控件可以实现什么样的效果呢?看下面效果:

    实现代码:

    bool _expand = false;
    
    @override
    Widget build(BuildContext context) {
      return Column(
        children: <Widget>[
          Container(
            height: 45,
            color: Colors.green.withOpacity(.3),
            alignment: Alignment.centerRight,
            child: IconButton(
              icon: Icon(Icons.arrow_drop_down),
              onPressed: () {
                setState(() {
                  _expand = !_expand;
                });
              },
            ),
          ),
          _expand
              ? MergeableMaterial(
                  hasDividers: true,
                  elevation: 24,
                  children: [
                    MaterialSlice(
                        key: ValueKey(1),
                        child: Container(
                          height: 200,
                          color: Colors.green.withOpacity(.3),
                        ))
                  ],
                )
              : Container(),
          Container(
            height: 45,
            color: Colors.red.withOpacity(.3),
          ),
        ],
      );
    }
    

    看到这个效果是否想到了ExpansionPanelList呢?系统控件ExpansionPanelList就是使用此控件实现的。

    交流

    老孟Flutter博客地址(近200个控件用法):http://laomengit.com

    欢迎加入Flutter交流群(微信:laomengit)、关注公众号【老孟Flutter】:

  • 相关阅读:
    解决uniapp中app.vue的onlaunch不能跳转页面问题
    参数校验注解,备用
    码云推送项目总是没有权限
    一句话解释回调函数
    动态管理
    转:用jupyter notebook打开指定目录下的.ipynb文件
    gcn变体
    图4
    节点分类
    图3
  • 原文地址:https://www.cnblogs.com/mengqd/p/12832957.html
Copyright © 2011-2022 走看看