animation added.

main_production_RSG
Sikander Saleem 1 month ago
parent dc893b7836
commit 729b80d4dc

@ -27,10 +27,11 @@ class MultipleSelectionFullScreenDialog<T extends Base> extends StatefulWidget {
_SelectionBottomSheetState createState() => _SelectionBottomSheetState<T>(); _SelectionBottomSheetState createState() => _SelectionBottomSheetState<T>();
} }
class _SelectionBottomSheetState<T extends Base> extends State<MultipleSelectionFullScreenDialog<T>> { class _SelectionBottomSheetState<T extends Base> extends State<MultipleSelectionFullScreenDialog<T>> with SingleTickerProviderStateMixin {
late List<T> _selectedValue; // Now nullable late List<T> _selectedValue; // Now nullable
String query = ""; String query = "";
late AnimationController _animationController;
List<T>? get filteredList => widget.items?.where((element) => widget.builderString(element).toLowerCase().contains(query.toLowerCase())).toList(); List<T>? get filteredList => widget.items?.where((element) => widget.builderString(element).toLowerCase().contains(query.toLowerCase())).toList();
@ -40,12 +41,18 @@ class _SelectionBottomSheetState<T extends Base> extends State<MultipleSelection
// This ensures temporary selections don't affect parent until confirmed // This ensures temporary selections don't affect parent until confirmed
_selectedValue = List<T>.from(widget.selectedItem); _selectedValue = List<T>.from(widget.selectedItem);
super.initState(); super.initState();
_animationController = AnimationController(
duration: const Duration(milliseconds: 1200),
vsync: this,
);
_animationController.forward();
} }
FocusNode searchFocusNode = FocusNode(); FocusNode searchFocusNode = FocusNode();
@override @override
void dispose() { void dispose() {
_animationController.dispose();
searchFocusNode.dispose(); searchFocusNode.dispose();
super.dispose(); super.dispose();
} }
@ -132,8 +139,39 @@ class _SelectionBottomSheetState<T extends Base> extends State<MultipleSelection
itemCount: filteredList?.length, itemCount: filteredList?.length,
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
itemBuilder: (cxt, index) { itemBuilder: (cxt, index) {
// Calculate staggered animation delay
final delay = index * 0.08;
final animation = Tween<double>(begin: 0.0, end: 1.0).animate(
CurvedAnimation(
parent: _animationController,
curve: Interval(
delay.clamp(0.0, 0.8),
(delay + 0.3).clamp(0.0, 1.0),
curve: Curves.easeOut,
),
),
);
final slideAnimation = Tween<Offset>(
begin: const Offset(0.0, 0.3),
end: Offset.zero,
).animate(
CurvedAnimation(
parent: _animationController,
curve: Interval(
delay.clamp(0.0, 0.8),
(delay + 0.3).clamp(0.0, 1.0),
curve: Curves.easeOutCubic,
),
),
);
bool isDisabledItem = widget.disableItem != null && widget.disableItem?.identifier == filteredList![index].identifier; bool isDisabledItem = widget.disableItem != null && widget.disableItem?.identifier == filteredList![index].identifier;
return CheckboxListTile( return FadeTransition(
opacity: animation,
child: SlideTransition(
position: slideAnimation,
child: CheckboxListTile(
value: checkItContains(filteredList![index]), value: checkItContains(filteredList![index]),
dense: true, dense: true,
controlAffinity: ListTileControlAffinity.leading, controlAffinity: ListTileControlAffinity.leading,
@ -161,6 +199,8 @@ class _SelectionBottomSheetState<T extends Base> extends State<MultipleSelection
widget.builderString(filteredList![index]).cleanupWhitespace.capitalizeFirstOfEach ?? "", widget.builderString(filteredList![index]).cleanupWhitespace.capitalizeFirstOfEach ?? "",
style: Theme.of(context).textTheme.bodyLarge, style: Theme.of(context).textTheme.bodyLarge,
), ),
),
),
); );
}), }),
), ),

@ -26,10 +26,11 @@ class SelectionFullScreenDialog<T extends Base> extends StatefulWidget {
_SelectionBottomSheetState createState() => _SelectionBottomSheetState<T>(); _SelectionBottomSheetState createState() => _SelectionBottomSheetState<T>();
} }
class _SelectionBottomSheetState<T extends Base> extends State<SelectionFullScreenDialog<T>> { class _SelectionBottomSheetState<T extends Base> extends State<SelectionFullScreenDialog<T>> with SingleTickerProviderStateMixin {
T? _selectedValue; // Now nullable T? _selectedValue; // Now nullable
String query = ""; String query = "";
late AnimationController _animationController;
List<T>? get filteredList => widget.items?.where((element) => widget.builderString(element).toLowerCase().contains(query.toLowerCase())).toList(); List<T>? get filteredList => widget.items?.where((element) => widget.builderString(element).toLowerCase().contains(query.toLowerCase())).toList();
@ -37,12 +38,18 @@ class _SelectionBottomSheetState<T extends Base> extends State<SelectionFullScre
void initState() { void initState() {
_selectedValue = widget.selectedItem; _selectedValue = widget.selectedItem;
super.initState(); super.initState();
_animationController = AnimationController(
duration: const Duration(milliseconds: 1200),
vsync: this,
);
_animationController.forward();
} }
FocusNode searchFocusNode = FocusNode(); FocusNode searchFocusNode = FocusNode();
@override @override
void dispose() { void dispose() {
_animationController.dispose();
searchFocusNode.dispose(); searchFocusNode.dispose();
super.dispose(); super.dispose();
} }
@ -129,8 +136,39 @@ class _SelectionBottomSheetState<T extends Base> extends State<SelectionFullScre
itemCount: filteredList?.length, itemCount: filteredList?.length,
padding: EdgeInsets.only(bottom: _selectedValue != null ? 4.toScreenHeight : 48.toScreenHeight), padding: EdgeInsets.only(bottom: _selectedValue != null ? 4.toScreenHeight : 48.toScreenHeight),
itemBuilder: (cxt, index) { itemBuilder: (cxt, index) {
// Calculate staggered animation delay
final delay = index * 0.08;
final animation = Tween<double>(begin: 0.0, end: 1.0).animate(
CurvedAnimation(
parent: _animationController,
curve: Interval(
delay.clamp(0.0, 0.8),
(delay + 0.3).clamp(0.0, 1.0),
curve: Curves.easeOut,
),
),
);
final slideAnimation = Tween<Offset>(
begin: const Offset(0.0, 0.3),
end: Offset.zero,
).animate(
CurvedAnimation(
parent: _animationController,
curve: Interval(
delay.clamp(0.0, 0.8),
(delay + 0.3).clamp(0.0, 1.0),
curve: Curves.easeOutCubic,
),
),
);
bool isDisabledItem = widget.disableItem != null && widget.disableItem?.identifier == filteredList![index].identifier; bool isDisabledItem = widget.disableItem != null && widget.disableItem?.identifier == filteredList![index].identifier;
return Theme( return FadeTransition(
opacity: animation,
child: SlideTransition(
position: slideAnimation,
child: Theme(
data: Theme.of(context).copyWith( data: Theme.of(context).copyWith(
radioTheme: RadioThemeData( radioTheme: RadioThemeData(
fillColor: MaterialStateColor.resolveWith((states) { fillColor: MaterialStateColor.resolveWith((states) {
@ -164,6 +202,8 @@ class _SelectionBottomSheetState<T extends Base> extends State<SelectionFullScre
style: Theme.of(context).textTheme.bodyLarge?.copyWith(color: isDisabledItem ? AppColor.neutral20 : null), style: Theme.of(context).textTheme.bodyLarge?.copyWith(color: isDisabledItem ? AppColor.neutral20 : null),
), ),
), ),
),
),
); );
}), }),
), ),

Loading…
Cancel
Save