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

如何在Flutter中实现指定样式的Expansion Panel并调整高度?

Fixes for Your Flutter ExpansionPanel Issues

Here's the corrected code with explanations for each problem:

Widget taskTileTest(List<Task> taskList, Task? expandedTask, Function(Task, bool) onExpansionChanged, BuildContext context) {
  return Padding(
    padding: const EdgeInsets.only(right: 30, left: 30, bottom: 20),
    child: Container(
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(15),
        border: Border.all(width: 0.4),
      ),
      clipBehavior: Clip.hardEdge, // Replaces ClipRRect for cleaner clipping
      child: ExpansionPanelList.radio(
        backgroundColor: Colors.transparent, // Make outer container's border visible
        expandedValue: expandedTask, // Mandatory: Track currently expanded panel
        expansionCallback: (Task task, bool isExpanded) {
          onExpansionChanged(task, isExpanded); // Handle expansion state change
        },
        children: taskList
            .map((task) => ExpansionPanelRadio(
                  value: task,
                  headerBuilder: (ctx, isOpen) => SizedBox(
                    height: 60, // Fixed height for header
                    child: Row(
                      crossAxisAlignment: CrossAxisAlignment.center,
                      children: [
                        Checkbox(
                          shape: const RoundedRectangleBorder(
                              borderRadius: BorderRadius.all(Radius.circular(5.0))),
                          splashRadius: 10,
                          checkColor: Colors.white,
                          fillColor: MaterialStateProperty.all<Color>(
                            Constants.appThemeColor,
                          ),
                          value: task.isDone,
                          onChanged: task.isDeleted == false
                              ? (bool? value) {
                                  context.read<TaskBloc>().add(UpdateTask(task: task));
                                }
                              : null,
                        ),
                        Expanded( // Prevent horizontal overflow on small screens
                          child: Column(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: [
                              Text.rich(
                                TextSpan(text: task.title), // Dynamic task title
                                overflow: TextOverflow.ellipsis,
                                style: TextStyle(
                                  fontFamily: 'Helvatica_lite',
                                  decoration: task.isDone ? TextDecoration.lineThrough : TextDecoration.none,
                                  fontWeight: FontWeight.bold,
                                  fontSize: 15,
                                  color: Colors.black,
                                ),
                              ),
                              const SizedBox(height: 4),
                              Text(
                                '${task.day} | ${task.time}', // Dynamic date/time
                                style: const TextStyle(
                                  fontSize: 13,
                                  fontFamily: 'Helvatica_lite',
                                  color: Colors.grey,
                                ),
                              )
                            ],
                          ),
                        )
                      ],
                    ),
                  ),
                  body: SizedBox( // Control body height if needed
                    height: 100, // Example fixed height for expanded panel
                    child: Padding(
                      padding: const EdgeInsets.all(16.0),
                      child: Text(task.description), // Dynamic body content
                    ),
                  ),
                ))
            .toList(),
      ),
    ),
  );
}

Key Fixes & Explanations:

  1. Mandatory ExpansionPanelList.radio Properties:

    • Added expandedValue to track which panel is open.
    • Added expansionCallback to handle state changes when panels expand/collapse. You'll manage this state in your parent widget (via setState or Bloc).
  2. Header Height Control:

    • Wrapped the header Row in a SizedBox with height: 60 to enforce a consistent header size. Adjust this value to match your design.
  3. Layout Improvements:

    • Replaced ClipRRect with Container's clipBehavior: Clip.hardEdge for cleaner border-radius clipping.
    • Set ExpansionPanelList.radio's backgroundColor to transparent so the outer container's border is visible (default white would hide it).
    • Used Expanded on the task details column to avoid horizontal overflow on smaller screens.
  4. Dynamic Content:

    • Replaced hardcoded text with values from the Task object (task.title, task.day, task.time). Adjust these to match your actual Task class properties.
  5. Body Height Control:

    • Wrapped the body content in a SizedBox with a fixed height to control the expanded panel's size. Remove this if you want the body to adapt to its content.

Usage in Parent Widget:

If using a stateful widget, manage the expanded state like this:

class YourParentWidget extends StatefulWidget {
  @override
  State<YourParentWidget> createState() => _YourParentWidgetState();
}

class _YourParentWidgetState extends State<YourParentWidget> {
  Task? _expandedTask;

  @override
  Widget build(BuildContext context) {
    // Assume taskList is fetched from Bloc or local state
    return taskTileTest(
      taskList,
      _expandedTask,
      (Task task, bool isExpanded) {
        setState(() {
          _expandedTask = isExpanded ? task : null;
        });
      },
      context,
    );
  }
}

Additional Notes:

  • If using Bloc, replace setState with a Bloc event to track the expanded panel globally.
  • Adjust height values in SizedBox for header/body to match your design needs.
  • Ensure your Task class overrides == and hashCode or has a unique ID for ExpansionPanelRadio to track panels correctly.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 12:10:32