Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 2.2.0
* New Feature:
- Only trailing can toggle the state: `isOnlyTrailingDoToggle` [#42](https://github.com/congthanhng/Expansion-Tile-Group/pull/42)
* Update
- Example with new feature

## 2.1.0
* New Feature:
- Add new way to implement *group* feature: ExpansionGroupController
Expand Down
69 changes: 38 additions & 31 deletions example/lib/use_cases/item/interaction_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class _InteractionViewState extends State<InteractionView> {
bool isHideSubtitle = false;
bool isHasTrailing = true;
bool isDefaultVerticalPadding = true;
bool isOnlyTrailingDoToggle = false;
final GlobalKey<ExpansionTileCoreState> key0 = GlobalKey();

final listIcon = <Widget>[
Expand Down Expand Up @@ -45,13 +46,13 @@ class _InteractionViewState extends State<InteractionView> {
fontSize: 16, color: Colors.red, fontWeight: FontWeight.w600)),
ExpansionTileItem.outlined(
expansionKey: key0,
expandedAlignment: Alignment.topLeft,
isEnableExpanded: isEnableExpanded,
isHideSubtitleOnExpanded: isHideSubtitle,
isHasTrailing: isHasTrailing,
isDefaultVerticalPadding: isDefaultVerticalPadding,
trailingIcon: listIcon[currentIcon % listIcon.length],
expendedBorderColor: Colors.grey,
isOnlyTrailingDoToggle: isOnlyTrailingDoToggle,
title: const Text('ExpansionTileItem Results'),
subtitle: const Text(
'Subtitle',
Expand All @@ -70,63 +71,69 @@ class _InteractionViewState extends State<InteractionView> {
return Column(children: [
const Divider(),
_buildRow(context,
title: 'Lock expanded state so that you can NOT expand anymore',
button: ElevatedButton.icon(
icon: Icon(isEnableExpanded ? Icons.lock_outline : Icons.lock_open),
label: Text(isEnableExpanded ? 'Do Lock' : 'Do Unlock'),
onPressed: () {
title: 'Do I need to enable expanded state?',
button: Checkbox(
value: isEnableExpanded,
onChanged: (value) {
setState(() {
isEnableExpanded = !isEnableExpanded;
isEnableExpanded = value ?? false;
});
},
)),
const Divider(),
_buildRow(context,
title: 'Hide the subtitle whenever you expand the view',
button: ElevatedButton.icon(
icon: Icon(isHideSubtitle
? Icons.visibility_outlined
: Icons.visibility_off_outlined),
label: Text(isHideSubtitle ? 'Do Show' : 'Do Hide'),
onPressed: () {
title: 'Do I need to hide the subtitle whenever I expanded the view?',
button: Checkbox(
value: isHideSubtitle,
onChanged: (value) {
setState(() {
isHideSubtitle = !isHideSubtitle;
isHideSubtitle = value ?? false;
});
},
)),
const Divider(),
_buildRow(context,
title: 'Remove completely trailing not like ExpansionTile',
button: ElevatedButton.icon(
icon: Icon(isHasTrailing ? Icons.remove : Icons.add),
label: Text(isHasTrailing ? 'Remove trailing' : 'Add trailing'),
onPressed: () {
title:
'Do I need to use ExpansionTile default trailing or remove completely it?',
button: Checkbox(
value: isHasTrailing,
onChanged: (value) {
setState(() {
isHasTrailing = !isHasTrailing;
isHasTrailing = value ?? false;
});
},
)),
const Divider(),
_buildRow(context,
title: 'Remove completely default vertical padding of ExpansionTile',
button: ElevatedButton.icon(
icon: Icon(isDefaultVerticalPadding ? Icons.remove : Icons.add),
label: Text(isDefaultVerticalPadding
? 'Remove Default Padding'
: 'Add Default Padding'),
onPressed: () {
title:
'Do I need to use ExpansionTile default vertical padding or remove it?',
button: Checkbox(
value: isDefaultVerticalPadding,
onChanged: (value) {
setState(() {
isDefaultVerticalPadding = value ?? false;
});
},
)),
const Divider(),
_buildRow(context,
title: 'Do I need to use just the trailing to toggle the state?',
button: Checkbox(
value: isOnlyTrailingDoToggle,
onChanged: (value) {
setState(() {
isDefaultVerticalPadding = !isDefaultVerticalPadding;
isOnlyTrailingDoToggle = value ?? false;
});
},
)),
const Divider(),
_buildRow(context,
title: 'Change Trailing Icon with keeping rotate animation',
title:
'Do I need to change trailing icon with keeping rotate animation?',
button: ElevatedButton.icon(
icon: listIcon[currentIcon % listIcon.length],
iconAlignment: IconAlignment.end,
label: const Text('Change icon'),
label: const Text('Tap to change'),
onPressed: () {
setState(() {
currentIcon = currentIcon + 1;
Expand Down
26 changes: 26 additions & 0 deletions example/lib/use_cases/item/more_example_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,32 @@ class MoreCustomView extends StatelessWidget {
const SizedBox(
height: 16,
),
ExpansionTileItem(
initiallyExpanded: false,
title: const Text(
'Title does not toggle the expansion state, but trail icon does #42'),
backgroundColor: Colors.red,
collapsedBackgroundColor: Colors.yellow,
textColor: Colors.white,
collapsedBorderColor: Colors.pink,
expendedBorderColor: Colors.blue,
iconColor: Colors.greenAccent,
collapsedIconColor: Colors.green,
isHasLeftBorder: true,
isHasTopBorder: true,
isHasRightBorder: true,
isHasBottomBorder: true,
borderRadius: BorderRadius.circular(8),
isOnlyTrailingDoToggle: true,
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 5,
blurRadius: 7,
offset: const Offset(0, 3), // changes position of shadow
),
],
children: _buildDefaultChildren(context)),
const SizedBox(
height: 32,
),
Expand Down
2 changes: 1 addition & 1 deletion example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ packages:
path: ".."
relative: true
source: path
version: "2.1.0"
version: "2.2.0"
fake_async:
dependency: transitive
description:
Expand Down
133 changes: 73 additions & 60 deletions lib/src/core/expansion_tile_core.dart
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ class ExpansionTileCore extends StatefulWidget {
this.isEnableExpanded = true,
this.isDefaultVerticalPadding = true,
this.isHideSubtitleOnExpanded = false,
this.isOnlyTrailingDoToggle = false,
this.trailingIcon,
}) : assert(
expandedCrossAxisAlignment != CrossAxisAlignment.baseline,
Expand Down Expand Up @@ -357,6 +358,9 @@ class ExpansionTileCore extends StatefulWidget {
///This property used to override the default trailing icon.
final Widget? trailingIcon;

///The title does NOT toggle the expansion state, but the trailing icon does
final bool isOnlyTrailingDoToggle;

@override
State<ExpansionTileCore> createState() => ExpansionTileCoreState();
}
Expand Down Expand Up @@ -504,7 +508,8 @@ class ExpansionTileCoreState extends State<ExpansionTileCore>
ListTileControlAffinity.trailing) {
return null;
}
return _buildIcon(context);
if (!widget.isOnlyTrailingDoToggle) return _buildIcon(context);
return GestureDetector(onTap: _handleTap, child: _buildIcon(context));
}

Widget _buildChildren(BuildContext context, Widget? child) {
Expand Down Expand Up @@ -546,65 +551,7 @@ class ExpansionTileCoreState extends State<ExpansionTileCore>
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
widget.isDefaultVerticalPadding
? ListTileTheme.merge(
iconColor: _iconColor.value ?? expansionTileTheme.iconColor,
textColor: _headerColor.value,
child: InkWell(
borderRadius: widget.borderRadius,
onTap: _handleTap,
child: ListTile(
dense: widget.isDefaultVerticalPadding ? null : true,
visualDensity: widget.isDefaultVerticalPadding
? null
: const VisualDensity(horizontal: 0, vertical: -4),
contentPadding:
widget.tilePadding ?? expansionTileTheme.tilePadding,
leading: widget.leading ?? _buildLeadingIcon(context),
title: widget.title,
subtitle: isHideSubtitle ? null : widget.subtitle,
trailing: widget.isHasTrailing == true
? widget.trailing ?? _buildTrailingIcon(context)
: null,
),
),
)
: IconTheme.merge(
data: IconThemeData(
color: _iconColor.value ?? expansionTileTheme.iconColor),
child: InkWell(
borderRadius: widget.borderRadius,
onTap: _handleTap,
child: Row(
children: [
widget.leading ??
_buildLeadingIcon(context) ??
const SizedBox.shrink(),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: widget.tilePadding ??
expansionTileTheme.tilePadding ??
const EdgeInsets.symmetric(horizontal: 8),
child: DefaultTextStyle(
style: TextStyle(color: _headerColor.value),
child: widget.title),
),
if (!isHideSubtitle)
widget.subtitle ?? const SizedBox.shrink(),
],
),
),
widget.isHasTrailing == true
? widget.trailing ??
_buildTrailingIcon(context) ??
const SizedBox.shrink()
: const SizedBox.shrink(),
],
),
)),
_buildMainTitle(context),
ClipRect(
child: Align(
alignment: widget.expandedAlignment ??
Expand All @@ -618,6 +565,72 @@ class ExpansionTileCoreState extends State<ExpansionTileCore>
);
}

Widget _buildMainTitle(BuildContext context) {
final ExpansionTileThemeData expansionTileTheme =
ExpansionTileTheme.of(context);
if (widget.isDefaultVerticalPadding) {
return ListTileTheme.merge(
iconColor: _iconColor.value ?? expansionTileTheme.iconColor,
textColor: _headerColor.value,
child: InkWell(
borderRadius: widget.borderRadius,
onTap: widget.isOnlyTrailingDoToggle ? null : _handleTap,
child: ListTile(
dense: widget.isDefaultVerticalPadding ? null : true,
visualDensity: widget.isDefaultVerticalPadding
? null
: const VisualDensity(horizontal: 0, vertical: -4),
contentPadding:
widget.tilePadding ?? expansionTileTheme.tilePadding,
leading: widget.leading ?? _buildLeadingIcon(context),
title: widget.title,
subtitle: isHideSubtitle ? null : widget.subtitle,
trailing: widget.isHasTrailing == true
? widget.trailing ?? _buildTrailingIcon(context)
: null,
),
),
);
}

return IconTheme.merge(
data: IconThemeData(
color: _iconColor.value ?? expansionTileTheme.iconColor),
child: InkWell(
borderRadius: widget.borderRadius,
onTap: widget.isOnlyTrailingDoToggle ? null : _handleTap,
child: Row(
children: [
widget.leading ??
_buildLeadingIcon(context) ??
const SizedBox.shrink(),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: widget.tilePadding ??
expansionTileTheme.tilePadding ??
const EdgeInsets.symmetric(horizontal: 8),
child: DefaultTextStyle(
style: TextStyle(color: _headerColor.value),
child: widget.title),
),
if (!isHideSubtitle)
widget.subtitle ?? const SizedBox.shrink(),
],
),
),
widget.isHasTrailing == true
? widget.trailing ??
_buildTrailingIcon(context) ??
const SizedBox.shrink()
: const SizedBox.shrink(),
],
),
));
}

@override
void didChangeDependencies() {
final ThemeData theme = Theme.of(context);
Expand Down
1 change: 1 addition & 0 deletions lib/src/types/expansion_tile_card.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class ExpansionTileCard extends ExpansionTileItem {
super.isEnableExpanded,
super.isDefaultVerticalPadding,
super.isHideSubtitleOnExpanded,
super.isOnlyTrailingDoToggle,
super.trailingIcon,
this.elevation = 3.0,
super.controller,
Expand Down
1 change: 1 addition & 0 deletions lib/src/types/expansion_tile_flat.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class ExpansionTileFlat extends ExpansionTileItem {
super.isEnableExpanded,
super.isDefaultVerticalPadding,
super.isHideSubtitleOnExpanded,
super.isOnlyTrailingDoToggle,
super.trailingIcon,
super.controller,
super.index,
Expand Down
Loading