I’m a highschool pupil making an attempt to create a enjoyable cellular utility for understanding. I’m presently making an attempt to develop this display screen to assist folks create their exercises – however want some assist ending it. Principally, I’m making an attempt to create a tab view on the prime, which has 5 plus buttons – when a consumer clicks on a plus button, a dialog field ought to pop up, asking for the exercise title. Then, when the consumer inputs the exercise title, the title ought to take the place of the clicked plus button. Nonetheless there may be one rule with this:
- A plus button can solely be clicked if the previous one has been crammed in – for instance if I click on button 2 with out placing a exercise title in for button 1, it should not work
As well as, I need it in order that the textual content bins are clickable, and for now I simply need the title of the exercise to be printed. Every thing I stated above I’ve already achieved, however I want your assist changing it to a tab view format so I can swipe facet to facet to go to the subsequent exercise. As well as I do not know methods to implement the rule proper now so I want some assist with that too.
TLDR: I need assistance making this display screen in a tab view, and in addition need assistance implementing the rule I stated above within the center
EDIT: An instance of what I need is should you go to the app My Exercise Plan after which go to their My Exercise tab
My code is under, and I’ve additionally included a display screen shot of what it ought to seem like (for now the whole lot is hardcoded)
IMAGE:
Picture
import 'bundle:flutter/materials.dart';
import 'bundle:workout_app/Screens/Elements/Widgets/footer.dart';
import 'bundle:shared_preferences/shared_preferences.dart';
import 'bundle:workout_app/colours.dart';
import 'bundle:workout_app/Screens/Elements/Widgets/footer.dart';
class workout_page extends StatefulWidget {
@override
_Main createState() => _Main();
}
class _Main extends State<workout_page> {
@override
var workoutMap = [
{
'name': 'arms',
'exercises': [
{
'name': 'Bicep Curl',
'musclesworked': ['bicep', 'tricep']
},
{
'title': 'Preacher Curl',
'musclesworked': ['bicep', 'tricep']
}
]
},
{
'title': 'legs',
'workouts': [
{
'name': 'Squat',
'musclesworked': ['quadriceps', 'hamstrings']
},
{
'title': 'Lunges',
'musclesworked': ['quadriceps', 'hamstrings']
}
]
},
{},
{},
{}
];
late Listing<String> workoutnames;
Listing<String> exercises = Listing.crammed(5, '');
int lastFilledIndex = -1;
bool showContainer = false;
String selectedWorkout="";
@override
void initState() {
tremendous.initState();
workoutnames = [];
for (var i = 0; i < workoutMap.size; i++) {
workoutnames
.add(workoutMap[i]['name'] == null ? '' : workoutMap[i]['name']);
}
// Discover the primary non-empty exercise title in workoutnames
selectedWorkout =
workoutnames.firstWhere((title) => title.isNotEmpty, orElse: () => '');
if (selectedWorkout.isNotEmpty) {
showContainer = true;
}
}
void _showDialog(int index) {
String newWorkout="";
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Textual content('Enter Exercise Identify'),
content material: TextField(
maxLength: 7,
onChanged: (worth) {
newWorkout = worth;
},
),
actions: [
TextButton(
child: Text('Cancel'),
onPressed: () {
Navigator.of(context).pop();
},
),
TextButton(
child: Text('Add'),
onPressed: () {
if (newWorkout.isNotEmpty) {
setState(() {
workoutnames[index] = newWorkout;
selectedWorkout = newWorkout;
showContainer = true;
});
Navigator.of(context).pop();
}
},
),
],
);
},
);
}
Widget construct(BuildContext context) {
Dimension dimension = MediaQuery.of(context).dimension;
return Scaffold(
physique: Stack(
kids: [
CustomScrollView(
slivers: [
SliverAppBar(
expandedHeight: size.height * .06,
titleSpacing: 15,
pinned: true,
backgroundColor: Colors.grey,
centerTitle: false,
bottom: PreferredSize(
preferredSize: const Size.fromHeight(0),
child: Row(
children: List.generate(workoutnames.length, (index) {
final isClickable = index <= lastFilledIndex + 1;
final workoutName = workoutnames[index];
ultimate isWorkoutEmpty = workoutName.isEmpty;
return Expanded(
youngster: Materials(
coloration: Colours.clear,
youngster: InkWell(
onTap: isWorkoutEmpty
? () => _showDialog(index)
: () {
setState(() {
selectedWorkout = workoutName;
showContainer = true;
});
},
youngster: isWorkoutEmpty
? Container(
width: 30, // Alter the width as wanted
peak: 30, // Alter the peak as wanted
ornament: BoxDecoration(
coloration: Shade.fromARGB(255, 0, 187, 255),
form: BoxShape.circle,
),
youngster: Icon(
Icons.add,
coloration: Shade.fromARGB(255, 255, 255, 255),
),
)
: Container(
width: 48,
margin: EdgeInsets.solely(
left: 10,
), // Alter the width as wanted
alignment: Alignment.middle,
ornament: BoxDecoration(
border: Border(
backside: BorderSide(
width: selectedWorkout == workoutName
? 1.5
: 0,
coloration: selectedWorkout == workoutName
? Colours.blue
: Colours.gray,
),
),
),
youngster: Padding(
padding: const EdgeInsets.all(8.0),
youngster: Textual content(
workoutName,
model: TextStyle(
coloration: selectedWorkout == workoutName
? Colours.black
: Colours.blue,
fontWeight: FontWeight.daring,
),
),
),
),
),
),
);
}),
),
),
),
if (showContainer)
SliverToBoxAdapter(
youngster: Container(
peak: dimension.peak * .3,
margin: EdgeInsets.solely(prime: 20, left: 10, proper: 10),
ornament: BoxDecoration(coloration: Colours.gray),
youngster: Textual content(
selectedWorkout,
model: TextStyle(
fontSize: 16,
fontWeight: FontWeight.daring,
coloration: Colours.purple,
),
),
),
),
],
),
Footer(tab: 'Exercise'),
],
),
);
}
}