I have such a column, consisting as it were of the title and the content created via List.generate
. Please tell me how I can create an animation of collapsing this list into a title, actually by clicking on the title itself?
Column(
children: [
GestureDetector(
onTap: () {},
child: Container(
color: Theme.of(context).sliderTheme.inactiveTrackColor,
width: MediaQuery.of(context).size.width,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 3),
child: Center(
child: Text('${category.name}',
style: Theme.of(context).textTheme.headline6.copyWith(
fontSize: 16,
color: Theme.of(context).selectedRowColor)),
),
),
),
),
Column(
children: List.generate(category.items.length, (index) {
return Container(
decoration: BoxDecoration(
border: (index 1) != category.items.length
? Border(
bottom: BorderSide(
color: Style.inactiveColorDark.withOpacity(1.0),
width: 0.5))
: null),
child: Padding(
padding:
const EdgeInsets.symmetric(vertical: 12.0, horizontal: 24),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Container(
width: 12,
height: 12,
decoration: BoxDecoration(
color: Color(int.parse(category.color)),
shape: BoxShape.circle),
),
SizedBox(
width: 12,
),
Text('${category.items[index].description}',
style: Theme.of(context)
.primaryTextTheme
.headline1
.copyWith(fontSize: 16)),
],
),
SwitchButton(
isActive: category.items[index].isAdded,
activeColor:
Theme.of(context).sliderTheme.activeTrackColor,
inactiveColor:
Theme.of(context).sliderTheme.inactiveTrackColor,
activeCircleColor:
Theme.of(context).sliderTheme.activeTickMarkColor,
inactiveCircleColor:
Theme.of(context).sliderTheme.inactiveTickMarkColor,
turnOn: () {
ChosenFeeling removingElement = ChosenFeeling(
id: 000,
isAdded: false,
);
// If chosen list is empty
if (chosenfeelings.isEmpty) {
chosenfeelings.add(ChosenFeeling(
isAdded: true, id: category.items[index].id));
} else {
// If user tap on switchButton 2 times
chosenfeelings.removeWhere((element) {
if (element.id != null &&
element.id == category.items[index].id) {
removingElement = element;
}
return _isNeedToRemoveWhenOn(
currentItem: category.items[index],
listItem: element,
);
});
// If list isn`t empty and chosen item isn`t in list
if (category.items[index].id != removingElement.id) {
chosenfeelings.add(ChosenFeeling(
id: category.items[index].id,
isAdded: true,
));
}
}
},
turnOff: () {
ChosenFeeling removingElement = ChosenFeeling(
id: 000,
isAdded: false,
);
if (chosenfeelings.isEmpty) {
chosenfeelings.add(ChosenFeeling(
id: category.items[index].id,
isAdded: false,
));
} else {
// If user tap on switchButton 2 times
chosenfeelings.removeWhere((element) {
if (element.id != null &&
element.id == category.items[index].id) {
removingElement = element;
}
return _isNeedToRemoveWhenOff(
currentItem: category.items[index],
listItem: element,
);
});
// If list isn`t empty and chosen item isn`t in list
if (category.items[index].id != removingElement.id) {
chosenfeelings.add(ChosenFeeling(
id: category.items[index].id,
isAdded: false,
));
}
}
},
)
],
),
),
);
}),
)
],
);
CodePudding user response:
The easiest way is to use expandable package for this purpose: https://pub.dev/packages/expandable
Create expandable controller outside of build method
final ExpandableController _expandableController = ExpandableController();
And then use it like this:
ExpandableNotifier(
controller: _expandableController,
child: Column(
children: [
Expandable(
collapsed: ExpandableButton(
child: titleWidget(),
),
expanded: Column(
children: [
ExpandableButton(
child: titleWidget(),
),
list(),
]
),
),
],
),
);
Don't forget to dispose controller after using it
@override
void dispose() {
_expandableController.dispose();
super.dispose();
}
Hope this helps. You can also create your own animation with a little research