flutter 学习笔记之ExpansionTile & ExpansionPanelList(展开闭合控件)

ExpansionTile其实就是一个有标题可以展开的控件

ExpansionTile({
    Key key,
    this.leading,//在文字前面的Widget
    @required this.title,//文字
    this.backgroundColor,//背景
    this.onExpansionChanged,//展开或者关闭的监听
    this.children = const [],//孩子
    this.trailing,//右侧图标
    this.initiallyExpanded = false,//默认是否展开
  })

ExpansionTile的很多属性都跟ListTitle类似,它内部就是使用ListTitle实现的,感兴趣的小伙伴可以去看下源码。

下面看一下demo核心 code:

构造你展开时你想要展示的widget数据
final List lzData = [
    BanchItem(
      title: '待接单',
      imgName: 'assets/images/待接单.png',
      number: 7,
    ),
    BanchItem(
      title: '跟进中',
      imgName: 'assets/images/待接单.png',
      number: 0,
    ),
    BanchItem(
      title: '留资查询',
      imgName: 'assets/images/待接单.png',
      number: 0,
    ),
    BanchItem(
      title: '拉新邀请',
      imgName: 'assets/images/待接单.png',
      number: 0,
    ),
  ];


Container(
              margin: EdgeInsets.fromLTRB(10, 10, 10, 0),
              child: ExpansionTile(
                backgroundColor: Colors.white,
                title: new Text(
                  '留资单',
                  style: new TextStyle(
                    color: Color(0xFF333333),
                    fontSize: 18,
                  ),
                ),
                trailing:  Image.asset('assets/images/收起.png'),
                initiallyExpanded: true,
                children: [
                  Wrap(
                    runSpacing: 10,
                    spacing: 10,
                    runAlignment: WrapAlignment.start,
                    crossAxisAlignment: WrapCrossAlignment.start,
                    children: lzData,
                  ),
                  Container(
                    height: 20,
                  )
                ],
              ),
            ),

效果如下 默认展开:

flutter 学习笔记之ExpansionTile & ExpansionPanelList(展开闭合控件)_第1张图片

效果还不错,但是会发现右侧的箭头并没有像默认的trailing那样会随着ExpansionTile的展开和关闭来做变换。这里需要我们自己处理一下箭头的变换动画。

动画核心code:

Animation animation;
  AnimationController animationController;
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    animationController = new AnimationController(
        vsync: this, duration: Duration(milliseconds: 200));
    animation = new Tween(begin: 0.0, end: 0.5).animate(animationController);
  }

  _changeTrailing(bool expand) {
    setState(() {
      if (expand) {
        animationController.reverse();
      } else {
        animationController.forward();
      }
    });
  }

把trailing改为RotationTransition 并添加onExpansionChanged 展开收起的回调方法:

trailing: RotationTransition(
                  turns: animation,
                  child: Image.asset('assets/images/收起.png'),
                ),
                onExpansionChanged: (expand) {
                  _changeTrailing(expand);
                },

到此 一个展开收起的控件就完美实现了,但是处理ExpansionTile,还有一个和他功能类似的控件ExpansionPanelList

ExpansionPanelList({
    Key key,
    this.children = const [],
    this.expansionCallback,//展开关闭回调
    this.animationDuration = kThemeAnimationDuration,//展开进行时间
  })
ExpansionPanel({
    @required this.headerBuilder,//标题构造器
    @required this.body,//内容区域
    this.isExpanded = false//是否展开
  })

基本使用也很简单,这里主要说一下注意事项:

1.headerBuilder不能自定义trailing ,或者说右侧他有一个写死的箭头 我们是没办法换成自己的图片的 

2.isExpanded需要手动设置,默认不会在点击header的时候改变 ,所以expansionCallback不实现的时候 点击是没效果的 这与RotationTransition不同

下面是一段使用的核心code:

Container(
                margin: EdgeInsets.fromLTRB(10, 10, 10, 0),
                child: ExpansionPanelList(
                  expansionCallback: (index, expand) {
                    setState(() {
                      orderExpand = !orderExpand;
                    });
                  },
                  children: [
                    ExpansionPanel(
                        isExpanded: orderExpand,
                        headerBuilder: (context, expand) {
                          return ListTile(
                            title: new Text(
                              '订单',
                              style: new TextStyle(
                                color: Color(0xFF333333),
                                fontSize: 18,
                              ),
                            ),
                            //不支持自定义右侧icon
                            // trailing: RotationTransition(
                            //   turns: animation,
                            //   child: Image.asset('assets/images/收起.png'),
                            // ),
                          );
                        },
                        body: Column(
                          children: [
                            Wrap(
                              runSpacing: 10,
                              spacing: 10,
                              runAlignment: WrapAlignment.start,
                              crossAxisAlignment: WrapCrossAlignment.start,
                              children: orderData,
                            ),
                            Container(
                              height: 20,
                            )
                          ],
                        ))
                  ],
                ))

 

你可能感兴趣的:(flutter开发)