flutter如何实现卡片折叠控件

在Flutter中如何实现一个可以折叠展开的卡片控件?希望支持自定义展开/折叠动画效果,并且能够动态控制折叠状态。求推荐比较优雅的实现方案或现成的插件库。

2 回复

使用Flutter实现卡片折叠控件,可通过ExpansionPanelListAnimatedContainer实现。ExpansionPanelList适合列表场景,AnimatedContainer适合自定义动画。

更多关于flutter如何实现卡片折叠控件的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中实现卡片折叠效果,可以通过ExpansionPanelListAnimatedContainer配合手势检测来实现。以下是两种常用方法:

1. 使用ExpansionPanelList(官方推荐)

适用于列表形式的折叠卡片,自带动画和手势支持。

import 'package:flutter/material.dart';

class ExpansionCardExample extends StatefulWidget {
  @override
  _ExpansionCardExampleState createState() => _ExpansionCardExampleState();
}

class _ExpansionCardExampleState extends State<ExpansionCardExample> {
  List<Item> _items = [
    Item(header: '标题1', body: '内容1'),
    Item(header: '标题2', body: '内容2'),
  ];

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      child: ExpansionPanelList(
        expansionCallback: (int index, bool isExpanded) {
          setState(() {
            _items[index].isExpanded = !isExpanded;
          });
        },
        children: _items.map<ExpansionPanel>((Item item) {
          return ExpansionPanel(
            headerBuilder: (BuildContext context, bool isExpanded) {
              return ListTile(title: Text(item.header));
            },
            body: ListTile(title: Text(item.body)),
            isExpanded: item.isExpanded,
          );
        }).toList(),
      ),
    );
  }
}

class Item {
  String header;
  String body;
  bool isExpanded;

  Item({required this.header, required this.body, this.isExpanded = false});
}

2. 使用AnimatedContainer + GestureDetector

适用于自定义程度更高的折叠效果:

class CustomFoldCard extends StatefulWidget {
  @override
  _CustomFoldCardState createState() => _CustomFoldCardState();
}

class _CustomFoldCardState extends State<CustomFoldCard> {
  bool _isExpanded = false;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        setState(() {
          _isExpanded = !_isExpanded;
        });
      },
      child: AnimatedContainer(
        duration: Duration(milliseconds: 300),
        height: _isExpanded ? 200 : 80, // 折叠/展开高度
        child: Card(
          child: Padding(
            padding: EdgeInsets.all(16),
            child: Column(
              children: [
                Row(
                  children: [
                    Text('标题'),
                    Icon(_isExpanded 
                      ? Icons.expand_less 
                      : Icons.expand_more),
                  ],
                ),
                if (_isExpanded) ...[
                  SizedBox(height: 20),
                  Text('详细内容...'),
                ]
              ],
            ),
          ),
        ),
      ),
    );
  }
}

选择建议:

  • 需要标准列表折叠效果 → 使用ExpansionPanelList
  • 需要高度自定义动画和样式 → 使用AnimatedContainer方案
  • 可配合ListView.builder实现动态列表
  • 可通过curve参数调整动画曲线

两种方案都支持平滑的动画过渡,可根据实际需求选择实现方式。

回到顶部