如何在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:
Mandatory ExpansionPanelList.radio Properties:
- Added
expandedValueto track which panel is open. - Added
expansionCallbackto handle state changes when panels expand/collapse. You'll manage this state in your parent widget (viasetStateor Bloc).
- Added
Header Height Control:
- Wrapped the header
Rowin aSizedBoxwithheight: 60to enforce a consistent header size. Adjust this value to match your design.
- Wrapped the header
Layout Improvements:
- Replaced
ClipRRectwithContainer'sclipBehavior: Clip.hardEdgefor cleaner border-radius clipping. - Set
ExpansionPanelList.radio'sbackgroundColorto transparent so the outer container's border is visible (default white would hide it). - Used
Expandedon the task details column to avoid horizontal overflow on smaller screens.
- Replaced
Dynamic Content:
- Replaced hardcoded text with values from the
Taskobject (task.title,task.day,task.time). Adjust these to match your actualTaskclass properties.
- Replaced hardcoded text with values from the
Body Height Control:
- Wrapped the body content in a
SizedBoxwith a fixed height to control the expanded panel's size. Remove this if you want the body to adapt to its content.
- Wrapped the body content in a
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
setStatewith a Bloc event to track the expanded panel globally. - Adjust
heightvalues inSizedBoxfor header/body to match your design needs. - Ensure your
Taskclass overrides==andhashCodeor has a unique ID forExpansionPanelRadioto track panels correctly.
内容的提问来源于stack exchange,提问作者mishalhaneef
相关产品推荐
相关产品推荐

