You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter如何设置ExpansionPanel图标居左标题居右并在头部下方加Divider

Flutter ExpansionPanel自定义布局实现方案

核心思路

默认的ExpansionPanel组件会默认在右侧渲染展开图标,标题放在左侧,我们可以通过关闭默认自带的图标、自定义头部布局的方式调整元素位置,同时在头部底部插入Divider即可实现需求,全程保留原生展开收起动画,不需要重写组件核心逻辑。

实现步骤

  • 首先给ExpansionPanelList设置hasIcon: false,关闭默认渲染在右侧的展开图标
  • 自定义headerBuilder返回的组件结构,按「左侧展开图标+右侧标题」的顺序排列Row子元素
  • 在头部组件外层嵌套Column,在头部内容下方插入Divider组件即可实现分割线效果
  • 保留canTapOnHeader: true配置,维持点击头部整体触发展开/收起的交互逻辑

示例代码

import 'package:flutter/material.dart';

class CustomExpansionPanelPage extends StatefulWidget {
  const CustomExpansionPanelPage({super.key});

  @override
  State<CustomExpansionPanelPage> createState() => _CustomExpansionPanelPageState();
}

class _CustomExpansionPanelPageState extends State<CustomExpansionPanelPage> {
  // 维护每个面板的展开状态
  final List<bool> _panelExpandedStatus = [false, false];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SingleChildScrollView(
        child: ExpansionPanelList(
          hasIcon: false, // 关闭默认右侧图标
          elevation: 1, // 可根据需求调整阴影大小
          expandedHeaderPadding: EdgeInsets.zero,
          expansionCallback: (panelIndex, isExpanded) {
            setState(() {
              _panelExpandedStatus[panelIndex] = !isExpanded;
            });
          },
          children: List.generate(2, (index) {
            return ExpansionPanel(
              isExpanded: _panelExpandedStatus[index],
              canTapOnHeader: true,
              headerBuilder: (context, isExpanded) {
                return Column(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    Padding(
                      padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
                      child: Row(
                        children: [
                          // 左侧保留原生风格展开图标
                          Icon(
                            isExpanded ? Icons.expand_less : Icons.expand_more,
                            size: 24,
                            color: Theme.of(context).iconTheme.color,
                          ),
                          const SizedBox(width: 12),
                          // 右侧放置标题内容
                          Expanded(
                            child: Text("面板标题${index+1}"),
                          ),
                        ],
                      ),
                    ),
                    // 头部下方添加分割线
                    const Divider(height: 1, thickness: 1, indent: 16, endIndent: 16),
                  ],
                );
              },
              // 展开区域内容
              body: Padding(
                padding: const EdgeInsets.all(16),
                child: Text("这里是面板${index+1}的展开内容"),
              ),
            );
          }),
        ),
      ),
    );
  }
}

可选优化点

  • 如果需要仅点击图标触发展开/收起,将canTapOnHeader设为false,同时把图标替换为IconButton,在onTap中手动修改对应面板的展开状态即可
  • 可通过调整Divider的color、thickness、indent等参数自定义分割线样式
  • 如需修改图标样式,直接替换Icon组件的图标、颜色、大小参数即可

内容的提问来源于stack exchange,提问作者Yashar Panahi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 01:15:05