I’ve a listing of widgets (workout routines) in my display. I need to make it in order that the workout routines are reorderable, so I can drag and drop them round and the order modifications. I REALLY need assistance as I have been engaged on this for DAYS and nonetheless HAVE NOT figured it out. Please assist me!
That is my COMPLETE code:
import 'bundle:flutter/materials.dart';
import 'bundle:workout_app/Screens/Elements/Widgets/footer.dart';
class workout_page extends StatefulWidget {
@override
_WorkoutPageState createState() => _WorkoutPageState();
}
class _WorkoutPageState extends State<workout_page>
with TickerProviderStateMixin {
late TabController _tabController;
late PageController _pageController;
TextEditingController _newTabController = TextEditingController();
late var currentPageIndx;
Listing<Map<String, dynamic>> workoutMap = [
{
'plan_name': 'My First Plan',
'content': [
{
'name': 'My First Workout',
'exercises': [
{
'name': 'Bicep Curl',
'musclesworked': ['bicep', 'tricep']
},
{
'identify': 'Preacher Curl',
'musclesworked': ['bicep', 'tricep']
},
{
'identify': 'Bicep Curl',
'musclesworked': ['bicep', 'tricep']
},
{
'identify': 'Preacher Curl',
'musclesworked': ['bicep', 'tricep']
},
{
'identify': 'Bicep Curl',
'musclesworked': ['bicep', 'tricep']
},
{
'identify': 'Preacher Curl',
'musclesworked': ['bicep', 'tricep']
},
{
'identify': 'Bicep Curl',
'musclesworked': ['bicep', 'tricep']
},
{
'identify': 'Preacher Curl',
'musclesworked': ['bicep', 'tricep']
}
]
}
]
},
{
'plan_name': 'My Second Plan',
'content material': [
{
'name': 'My Second Workout',
'exercises': [
{
'name': 'POOPY Curl',
'musclesworked': ['bicep', 'tricep']
},
{
'identify': 'Preacher Curl',
'musclesworked': ['bicep', 'tricep']
},
{
'identify': 'Bicep Curl',
'musclesworked': ['bicep', 'tricep']
},
{
'identify': 'Preacher Curl',
'musclesworked': ['bicep', 'tricep']
},
{
'identify': 'Bicep Curl',
'musclesworked': ['bicep', 'tricep']
},
{
'identify': 'Preacher Curl',
'musclesworked': ['bicep', 'tricep']
},
{
'identify': 'Bicep Curl',
'musclesworked': ['bicep', 'tricep']
},
{
'identify': 'Preacher Curl',
'musclesworked': ['bicep', 'tricep']
}
]
}
]
},
];
@override
void initState() {
tremendous.initState();
currentPageIndx = 1;
_tabController = TabController(
size: workoutMap[currentPageIndx]['content'].size +
(workoutMap[currentPageIndx]['content'].size < 4 ? 1 : 0),
vsync: this,
);
_pageController = PageController();
}
void _addTab() {
setState(() {
String newTabName = _newTabController.textual content;
Map<String, dynamic> newTab = {
'identify': newTabName,
'workout routines': [],
};
workoutMap[currentPageIndx]['content'].add(newTab);
_newTabController.clear();
_tabController = TabController(
size: workoutMap[currentPageIndx]['content'].size +
(workoutMap[currentPageIndx]['content'].size < 4 ? 1 : 0),
vsync: this,
);
});
}
@override
void dispose() {
tremendous.dispose();
}
@override
Widget construct(BuildContext context) {
var dimension = MediaQuery.of(context).dimension;
return Container(
little one: Materials(
coloration: Colours.inexperienced,
little one: DefaultTabController(
size: workoutMap[currentPageIndx]['content'].size +
(workoutMap[currentPageIndx]['content'].size < 4 ? 1 : 0),
little one: Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: Colour.fromRGBO(79, 79, 79, 1),
physique: Stack(
kids: [
CustomScrollView(
slivers: [
SliverAppBar(
titleSpacing: 15,
pinned: true,
elevation: 0,
backgroundColor: Color.fromARGB(255, 17, 17, 17),
centerTitle: false,
bottom: PreferredSize(
preferredSize: const Size.fromHeight(40),
child: Column(
children: [
Container(
color: Color.fromARGB(255, 17, 17, 17),
child: Row(
children: [
SizedBox(width: 20),
Text(
'Workout',
style: TextStyle(
color: Colors.white,
fontSize: 20,
),
),
Spacer(),
ElevatedButton(
onPressed: () => print('premium'),
style: ElevatedButton.styleFrom(
primary: Color.fromARGB(255, 35, 35, 35),
),
child: Text('Go Premium'),
),
SizedBox(width: 20),
],
),
),
Container(
ornament: BoxDecoration(
coloration: Colour.fromRGBO(68, 68, 68, 1),
),
little one: TabBar(
indicatorColor: Colours.gray,
controller: _tabController,
onTap: (index) {
if (index == _tabController.size - 1 &&
workoutMap[currentPageIndx]['content']
.size <
4) {
_tabController.animateTo(
_tabController.previousIndex);
} else {
_tabController.animateTo(index);
_pageController.jumpToPage(index);
}
},
tabs: [
...workoutMap[currentPageIndx]['content'].map(
(tab) => Tab(
textual content: tab['name'] as String,
),
),
if (workoutMap[currentPageIndx]['content']
.size <
4)
Container(
width: 40,
top: 40,
alignment: Alignment.heart,
little one: IconButton(
icon: Icon(Icons.add),
onPressed: () {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Textual content('Add Tab'),
content material: TextField(
controller: _newTabController,
ornament: InputDecoration(
hintText: 'Enter tab identify',
),
),
actions: [
TextButton(
child: Text('Cancel'),
onPressed: () {
Navigator.pop(context);
},
),
TextButton(
child: Text('Add'),
onPressed: () {
_addTab();
Navigator.pop(context);
},
),
],
),
);
},
),
),
],
),
),
],
),
),
),
SliverToBoxAdapter(
little one: SizedBox(
top: dimension.top - 170,
little one: PageView(
controller: _pageController,
onPageChanged: (index) {
if (index == _tabController.size - 1 &&
workoutMap[currentPageIndx]['content'].size <
4) {
_pageController.jumpToPage(_tabController.index);
} else {
_tabController.animateTo(index);
}
},
kids: [
...workoutMap[currentPageIndx]['content'].map(
(tab) => Container(
little one: tab['exercises'].size == 0
? Column(
mainAxisAlignment:
MainAxisAlignment.heart,
kids: [
Icon(
Icons.sentiment_very_dissatisfied,
size: size.width * 0.3,
color: Colors.white,
),
SizedBox(height: 10),
Text(
'This folder is empty. Add some workouts',
style:
TextStyle(color: Colors.white),
textAlign: TextAlign.center,
),
SizedBox(height: size.height * .1),
],
)
: Container(
top: dimension.top, // specify top
little one: ReorderableListView(
onReorder: (oldIndex, newIndex) {
if (newIndex > oldIndex) {
newIndex -= 1;
}
setState(() {
ultimate merchandise = tab['exercises']
.removeAt(oldIndex);
tab['exercises']
.insert(newIndex, merchandise);
});
},
kids:
tab['exercises'].map<Widget>(
(train) {
return Container(
key: ValueKey(train),
margin: EdgeInsets.all(5.0),
ornament: BoxDecoration(
coloration: Colours.black,
borderRadius:
BorderRadius.round(
10.0),
),
little one: Column(
kids: [
Container(
height: size.height * .15,
decoration: BoxDecoration(
color: Color.fromARGB(
255, 45, 45, 45),
borderRadius:
BorderRadius
.circular(10.0),
),
child: Stack(
children: [
Positioned(
top: 10,
left: 10,
child: Container(
width:
size.width *
.4,
child: ClipRRect(
borderRadius:
BorderRadius
.circular(
10.0),
child: Image
.network(
'https://i.giphy.com/media/14kdiJUblbWBXy/giphy.gif', // Replace with your GIF URL
),
),
),
),
Positioned(
top: 10,
left: size.width *
.4 +
20,
child: Column(
crossAxisAlignment:
CrossAxisAlignment
.start,
children: [
Text(
exercise[
'name'],
fashion: TextStyle(
coloration: Colour.fromARGB(
255,
255,
255,
255),
fontSize:
20,
fontWeight:
FontWeight
.daring),
),
Textual content(
'Muscle tissue Labored: n' +
(train['musclesworked']
as Listing)
.be part of(
', '), // be part of the checklist right into a string
fashion: TextStyle(
fontSize:
16,
coloration: Colours
.white), // modify fashion as wanted
),
],
),
),
],
),
),
SizedBox(top: 10),
Row(
kids: [
Spacer(),
Text(
'3 Sets', // Replace with your sets, reps, and weight data
style: TextStyle(
color: Colors.white,
),
textAlign:
TextAlign.center,
),
Spacer(),
Text(
'4 reps', // Replace with your sets, reps, and weight data
style: TextStyle(
color: Colors.white,
),
textAlign:
TextAlign.center,
),
Spacer(),
Text(
'30 kg', // Replace with your sets, reps, and weight data
style: TextStyle(
color: Colors.white,
),
textAlign:
TextAlign.center,
),
Spacer(),
],
),
SizedBox(top: 10),
],
),
);
},
).toList(),
)),
),
),
],
),
),
),
],
),
Footer(tab: 'Exercise'),
Positioned(
high: dimension.top,
left: 0,
proper: 0,
little one: Remodel.translate(
offset: Offset(0, -120),
little one: Middle(
little one: Container(
width: dimension.width * 0.8,
padding: EdgeInsets.solely(high: 5, backside: 5),
ornament: BoxDecoration(
coloration: Colour.fromARGB(255, 152, 152, 152)
.withOpacity(.9),
border: Border(
backside:
BorderSide(coloration: Colours.inexperienced, width: 2),
left: BorderSide(coloration: Colours.inexperienced, width: 2),
proper:
BorderSide(coloration: Colours.inexperienced, width: 2),
high: BorderSide(coloration: Colours.inexperienced, width: 2)),
borderRadius: BorderRadius.round(10.0)),
little one: Row(
kids: [
Spacer(),
Container(
width: 30,
height: 30,
child: ElevatedButton(
onPressed: () => {print('clicked')},
style: ElevatedButton.styleFrom(
padding: EdgeInsets.all(0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(1000.0),
),
primary: Color.fromARGB(255, 25, 112, 1),
),
child: Align(
alignment: Alignment.center,
child: Text(
'+',
style: TextStyle(fontSize: 25),
),
),
),
),
Spacer(),
Icon(
Icons.play_arrow_sharp,
color: Color.fromARGB(255, 25, 112, 1),
size: size.width * 0.11,
),
Spacer(),
Icon(Icons.more_horiz,
color: Color.fromARGB(255, 25, 112, 1),
size: size.width * .1),
Spacer(),
],
),
),
),
),
),
],
),
),
),
),
);
}
}
THANK YOU SO MUCH IN ADVANCE!!!!!!