My goal is to make the Floating Action Buttons (FABs) animate smoothly to fill the empty space when I pick one up using Draggable. However, I haven’t been able to achieve this.
I want to create an animation similar to iOS, where when you long-press and start dragging an app, the other apps smoothly slide into the empty space.
Likewise, when a FAB is dropped into the DragTarget area, instead of snapping into place instantly, I want it to animate smoothly into position.
You can watch a screen recording of my current progress at this link. However, I am unable to add animations. Right now, everything is rendered instantly in the widget tree without smooth transitions. Should I use a different widget for this
https://www.dosya.tc/server3/ss463k/Screen_Recording_2025-02-20_at_13.01.10.mov.html
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:rey_bank/UI/Widget/animated_fab.dart';
import 'package:rey_bank/UI/Widget/home_page_widget.dart';
import 'package:rey_bank/UI/Widget/no_animation_fab_widget.dart';
import 'package:rey_bank/core/cubits/setting_cubit.dart';
class ModifyQuickTransactionPage extends StatefulWidget {
const ModifyQuickTransactionPage({super.key});
@override
State<ModifyQuickTransactionPage> createState() =>
_ModifyQuickTransactionPageState();
}
class _ModifyQuickTransactionPageState
extends State<ModifyQuickTransactionPage> {
@override
void initState() {
super.initState();
getLanguage();
}
getLanguage() {
final state = context.read<SettingsCubit>().state;
if (state.language == 'English') {
setState(() {
labelContent = ['Deposit', 'Withdraw', 'Transfer'];
});
} else if (state.language == 'Türkçe') {
setState(() {
labelContent = ['Para Yatır', 'Para Çek', 'Para gönder'];
});
}
}
Widget buildDraggableFab(String tag) {
IconData icon;
String label;
switch (tag) {
case 'Deposit':
icon = Icons.arrow_upward;
label = labelContent[0];
break;
case 'Withdraw':
icon = Icons.arrow_downward;
label = labelContent[1];
break;
case 'Transfer':
icon = Icons.autorenew_outlined;
label = labelContent[0];
break;
default:
icon = Icons.abc;
label = '';
}
return Draggable<String>(
onDragStarted: () {
sizedBoxFuction();
},
data: tag,
feedback: Material(
color: Colors.transparent,
child: animatedFabWidget(() {}, icon, label),
),
childWhenDragging: SizedBox(
width: sizaedBox,
),
child: animatedFabWidget(() {}, icon, label),
);
}
Widget buildDroppedFab(String tag) {
IconData icon;
String label;
switch (tag) {
case 'Deposit':
icon = Icons.arrow_upward;
label = labelContent[0];
break;
case 'Withdraw':
icon = Icons.arrow_forward;
label = labelContent[1];
break;
case 'Transfer':
icon = Icons.autorenew_outlined;
label = labelContent[2];
break;
default:
icon = Icons.abc;
label = '';
}
return Draggable<String>(
data: tag,
feedback: Material(
color: Colors.transparent,
child: animatedFabWidget(() {}, icon, label),
),
childWhenDragging: const SizedBox(),
child: noAnimationFabWidget(() {}, icon, label),
);
}
sizedBoxFuction() async {
for (var i = 50; i > 0; i--) {
await Future.delayed(const Duration(milliseconds: 10));
setState(() {
sizaedBox = i.toDouble();
});
print(i);
print(sizaedBox);
}
}
List<String> labelContent = [];
List<String> draggableFabList = ['Deposit', 'Withdraw', 'Transfer'];
List<String> droppedFabList = [];
double sizaedBox = 50;
@override
Widget build(BuildContext context) {
return ConstrainedBox(
constraints: BoxConstraints(
minWidth: MediaQuery.of(context).size.width,
minHeight: MediaQuery.of(context).size.height -
MediaQuery.of(context).padding.bottom -
kBottomNavigationBarHeight -
MediaQuery.of(context).padding.top,
),
child: Center(
child:
Column(mainAxisAlignment: MainAxisAlignment.center, children: [
DragTarget<String>(
onAcceptWithDetails: (details) {
setState(() {
draggableFabList.remove(details.data);
droppedFabList.add(details.data);
});
},
builder: (context, candidateData, rejectedData) {
return containerWidget(
context: context,
height: 150,
child: Row(
children: droppedFabList
.map((element) => buildDroppedFab(element))
.toList(),
));
},
),
const SizedBox(
height: 20,
),
containerWidget(
context: context,
height: 150,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: draggableFabList
.map((element) => buildDraggableFab(element))
.toList()))
])));
}
}