I added an image picker to my page where the user need to put details for his category created. The problem is that image picker it’s used in the first page and in the second page created the widget doesn’t retrieve the data . for better explanation I will let a video here : https://imgur.com/a/7aIzY1y
What I should change to the post so I can make this work and also to transform this rounded rectangle container in a widget (from UserProfilePage)
here it’s the code :
<code> class WorkoutContentPage extends StatefulWidget {
const WorkoutContentPage({super.key});
@override
WorkoutContentPageState createState() => WorkoutContentPageState();
}
class WorkoutContentPageState extends State<WorkoutContentPage> {
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
Stream<QuerySnapshot<Map>>? stream;
String? userId;
String? nameprogram;
String? typeprogram;
String? typeequipment;
TextEditingController nameprogramController = TextEditingController();
TextEditingController typeprogramController = TextEditingController();
TextEditingController typeequipmentController = TextEditingController();
File? image;
Future pickImage() async {
try {
final image = await ImagePicker().pickImage(source: ImageSource.gallery);
if (image == null) return;
final imageTemp = File(image.path);
setState(() => this.image = imageTemp);
} on PlatformException catch (e) {
print('Failed to pick image: $e');
}
}
@override
void initState() {
userId = FirebaseAuth.instance.currentUser!.uid;
FirebaseFirestore.instance
.collection("Users")
.doc(userId)
.get()
.then((value) {
var data = value.data() as Map<String, dynamic>;
nameprogram = data["nameprogram"];
typeprogram = data["typeprogram"];
typeequipment = data["typeequipment"];
// Populate TextEditingControllers with existing data
nameprogramController.text = nameprogram ?? '';
typeprogramController.text = typeprogram ?? '';
typeequipmentController.text = typeequipment ?? '';
});
super.initState();
}
@override
void dispose() {
// Dispose of the controllers when the widget is disposed
nameprogramController.dispose();
typeprogramController.dispose();
typeequipmentController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text(
'Workout Content',
style: TextStyle(fontWeight: FontWeight.bold, color: Colors.white),
),
centerTitle: true,
backgroundColor: Colors.black,
),
body: Padding(
padding: const EdgeInsets.all(18.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
height: 30,
),
Center(
child: Column(children: [
Text(
'Add details about your entire workout program',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15),
),
SizedBox(
height: 20,
),
TextField(
controller: nameprogramController,
decoration: InputDecoration(
hintText: "Name of the program",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(18),
borderSide: BorderSide.none),
fillColor: Colors.black.withOpacity(0.1),
filled: true,
),
),
SizedBox(
height: 20,
),
TextField(
controller: typeprogramController,
decoration: InputDecoration(
hintText: "Type of program(ex: strength, cardio, yoga",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(18),
borderSide: BorderSide.none),
fillColor: Colors.black.withOpacity(0.1),
filled: true,
),
),
SizedBox(
height: 20,
),
TextField(
controller: typeequipmentController,
decoration: InputDecoration(
hintText: "Type of equipment used",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(18),
borderSide: BorderSide.none),
fillColor: Colors.black.withOpacity(0.1),
filled: true,
),
),
SizedBox(
height: 20,
),
Container(
width: 250,
height: 70,
child: ElevatedButton(
onPressed: () {
pickImage();
},
style: ElevatedButton.styleFrom(
shape: const StadiumBorder(),
padding: const EdgeInsets.symmetric(vertical: 16),
backgroundColor: Colors.black,
),
child: const Text(
"+Add photo/video for cover",
style: TextStyle(fontSize: 15, color: Colors.white),
),
),
),
SizedBox(
height: 20,
),
Text(
'We suggest you to do a short video of 10-15 sec with some exercise that your program has so the user can get an idea of what to expect'),
SizedBox(
height: 40,
),
Container(
width: 250,
height: 70,
child: ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => WorkoutContentPage()),
);
},
style: ElevatedButton.styleFrom(
shape: const StadiumBorder(),
padding: const EdgeInsets.symmetric(vertical: 16),
backgroundColor: Colors.black,
),
child: const Text(
"Set price",
style: TextStyle(fontSize: 15, color: Colors.white),
),
),
),
]))
],
),
),
bottomNavigationBar: BottomAppBar(
color: const Color.fromARGB(255, 240, 240, 240),
child: Container(
width: 50,
child: ElevatedButton(
onPressed: () {
FirebaseFirestore.instance.collection("Users").doc(userId).set({
"nameprogram": nameprogramController.text,
"typeprogram": typeprogramController.text,
"typeequipment": typeequipmentController.text,
}).then((_) {
// Navigate to the user profile page
Navigator.push(
context,
MaterialPageRoute(builder: (context) => UserProfilePage()),
);
});
},
style: ElevatedButton.styleFrom(
shape: const StadiumBorder(),
padding: const EdgeInsets.symmetric(vertical: 16),
backgroundColor: Colors.black,
),
child: Text(
'Continue',
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
),
)),
),
),
);
// ignore: dead_code
}
void _alertNoText(BuildContext context) {
Alert(
context: context,
type: AlertType.warning,
title: "Post",
desc: "You have not written any text",
buttons: [
DialogButton(
onPressed: () => Navigator.pop(context),
width: 120,
child: const Text(
"Close",
style: TextStyle(color: Colors.white, fontSize: 20),
),
)
],
).show();
}
}
class UserProfilePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final userId = FirebaseAuth.instance.currentUser!.uid;
File? image;
return Scaffold(
appBar: AppBar(
title: const Text('User Profile'),
),
body: FutureBuilder<DocumentSnapshot<Map<String, dynamic>>>(
future:
FirebaseFirestore.instance.collection("Users").doc(userId).get(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: CircularProgressIndicator());
}
if (snapshot.hasError) {
return const Center(child: Text('Error fetching data'));
}
if (!snapshot.hasData || !snapshot.data!.exists) {
return const Center(child: Text('No data found'));
}
final data = snapshot.data!.data()!;
final nameprogram = data["nameprogram"];
final typeprogram = data["typeprogram"];
final typeequipment = data["typeequipment"];
return Padding(
padding: EdgeInsets.only(top: 20, left: 10, right: 10),
child: Container(
height: 135,
width: MediaQuery.of(context).size.width * 0.90,
decoration: ShapeDecoration(
shape: RoundedRectangleBorder(
borderRadius:
new BorderRadius.all(new Radius.circular(10))),
color: Colors.white,
shadows: [
BoxShadow(
color: Colors.grey.shade400,
blurRadius: 5,
spreadRadius: 2,
),
],
),
child: Row(mainAxisSize: MainAxisSize.min, children: [
SizedBox(
width: 10,
),
image != null
? Image.file(image!)
: Text("No image selected"),
const SizedBox(width: 10), // space between image & Column
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(
height: 25,
),
Text('$nameprogram',
style: TextStyle(fontWeight: FontWeight.bold)),
SizedBox(
height: 5,
),
Text('type: $typeprogram',
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.grey)),
SizedBox(
height: 5,
),
Text('equipment: $typeequipment',
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.grey)),
],
)),
])));
},
),
);
}
}
</code>
<code> class WorkoutContentPage extends StatefulWidget {
const WorkoutContentPage({super.key});
@override
WorkoutContentPageState createState() => WorkoutContentPageState();
}
class WorkoutContentPageState extends State<WorkoutContentPage> {
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
Stream<QuerySnapshot<Map>>? stream;
String? userId;
String? nameprogram;
String? typeprogram;
String? typeequipment;
TextEditingController nameprogramController = TextEditingController();
TextEditingController typeprogramController = TextEditingController();
TextEditingController typeequipmentController = TextEditingController();
File? image;
Future pickImage() async {
try {
final image = await ImagePicker().pickImage(source: ImageSource.gallery);
if (image == null) return;
final imageTemp = File(image.path);
setState(() => this.image = imageTemp);
} on PlatformException catch (e) {
print('Failed to pick image: $e');
}
}
@override
void initState() {
userId = FirebaseAuth.instance.currentUser!.uid;
FirebaseFirestore.instance
.collection("Users")
.doc(userId)
.get()
.then((value) {
var data = value.data() as Map<String, dynamic>;
nameprogram = data["nameprogram"];
typeprogram = data["typeprogram"];
typeequipment = data["typeequipment"];
// Populate TextEditingControllers with existing data
nameprogramController.text = nameprogram ?? '';
typeprogramController.text = typeprogram ?? '';
typeequipmentController.text = typeequipment ?? '';
});
super.initState();
}
@override
void dispose() {
// Dispose of the controllers when the widget is disposed
nameprogramController.dispose();
typeprogramController.dispose();
typeequipmentController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text(
'Workout Content',
style: TextStyle(fontWeight: FontWeight.bold, color: Colors.white),
),
centerTitle: true,
backgroundColor: Colors.black,
),
body: Padding(
padding: const EdgeInsets.all(18.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
height: 30,
),
Center(
child: Column(children: [
Text(
'Add details about your entire workout program',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15),
),
SizedBox(
height: 20,
),
TextField(
controller: nameprogramController,
decoration: InputDecoration(
hintText: "Name of the program",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(18),
borderSide: BorderSide.none),
fillColor: Colors.black.withOpacity(0.1),
filled: true,
),
),
SizedBox(
height: 20,
),
TextField(
controller: typeprogramController,
decoration: InputDecoration(
hintText: "Type of program(ex: strength, cardio, yoga",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(18),
borderSide: BorderSide.none),
fillColor: Colors.black.withOpacity(0.1),
filled: true,
),
),
SizedBox(
height: 20,
),
TextField(
controller: typeequipmentController,
decoration: InputDecoration(
hintText: "Type of equipment used",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(18),
borderSide: BorderSide.none),
fillColor: Colors.black.withOpacity(0.1),
filled: true,
),
),
SizedBox(
height: 20,
),
Container(
width: 250,
height: 70,
child: ElevatedButton(
onPressed: () {
pickImage();
},
style: ElevatedButton.styleFrom(
shape: const StadiumBorder(),
padding: const EdgeInsets.symmetric(vertical: 16),
backgroundColor: Colors.black,
),
child: const Text(
"+Add photo/video for cover",
style: TextStyle(fontSize: 15, color: Colors.white),
),
),
),
SizedBox(
height: 20,
),
Text(
'We suggest you to do a short video of 10-15 sec with some exercise that your program has so the user can get an idea of what to expect'),
SizedBox(
height: 40,
),
Container(
width: 250,
height: 70,
child: ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => WorkoutContentPage()),
);
},
style: ElevatedButton.styleFrom(
shape: const StadiumBorder(),
padding: const EdgeInsets.symmetric(vertical: 16),
backgroundColor: Colors.black,
),
child: const Text(
"Set price",
style: TextStyle(fontSize: 15, color: Colors.white),
),
),
),
]))
],
),
),
bottomNavigationBar: BottomAppBar(
color: const Color.fromARGB(255, 240, 240, 240),
child: Container(
width: 50,
child: ElevatedButton(
onPressed: () {
FirebaseFirestore.instance.collection("Users").doc(userId).set({
"nameprogram": nameprogramController.text,
"typeprogram": typeprogramController.text,
"typeequipment": typeequipmentController.text,
}).then((_) {
// Navigate to the user profile page
Navigator.push(
context,
MaterialPageRoute(builder: (context) => UserProfilePage()),
);
});
},
style: ElevatedButton.styleFrom(
shape: const StadiumBorder(),
padding: const EdgeInsets.symmetric(vertical: 16),
backgroundColor: Colors.black,
),
child: Text(
'Continue',
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
),
)),
),
),
);
// ignore: dead_code
}
void _alertNoText(BuildContext context) {
Alert(
context: context,
type: AlertType.warning,
title: "Post",
desc: "You have not written any text",
buttons: [
DialogButton(
onPressed: () => Navigator.pop(context),
width: 120,
child: const Text(
"Close",
style: TextStyle(color: Colors.white, fontSize: 20),
),
)
],
).show();
}
}
class UserProfilePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final userId = FirebaseAuth.instance.currentUser!.uid;
File? image;
return Scaffold(
appBar: AppBar(
title: const Text('User Profile'),
),
body: FutureBuilder<DocumentSnapshot<Map<String, dynamic>>>(
future:
FirebaseFirestore.instance.collection("Users").doc(userId).get(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: CircularProgressIndicator());
}
if (snapshot.hasError) {
return const Center(child: Text('Error fetching data'));
}
if (!snapshot.hasData || !snapshot.data!.exists) {
return const Center(child: Text('No data found'));
}
final data = snapshot.data!.data()!;
final nameprogram = data["nameprogram"];
final typeprogram = data["typeprogram"];
final typeequipment = data["typeequipment"];
return Padding(
padding: EdgeInsets.only(top: 20, left: 10, right: 10),
child: Container(
height: 135,
width: MediaQuery.of(context).size.width * 0.90,
decoration: ShapeDecoration(
shape: RoundedRectangleBorder(
borderRadius:
new BorderRadius.all(new Radius.circular(10))),
color: Colors.white,
shadows: [
BoxShadow(
color: Colors.grey.shade400,
blurRadius: 5,
spreadRadius: 2,
),
],
),
child: Row(mainAxisSize: MainAxisSize.min, children: [
SizedBox(
width: 10,
),
image != null
? Image.file(image!)
: Text("No image selected"),
const SizedBox(width: 10), // space between image & Column
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(
height: 25,
),
Text('$nameprogram',
style: TextStyle(fontWeight: FontWeight.bold)),
SizedBox(
height: 5,
),
Text('type: $typeprogram',
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.grey)),
SizedBox(
height: 5,
),
Text('equipment: $typeequipment',
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.grey)),
],
)),
])));
},
),
);
}
}
</code>
class WorkoutContentPage extends StatefulWidget {
const WorkoutContentPage({super.key});
@override
WorkoutContentPageState createState() => WorkoutContentPageState();
}
class WorkoutContentPageState extends State<WorkoutContentPage> {
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
Stream<QuerySnapshot<Map>>? stream;
String? userId;
String? nameprogram;
String? typeprogram;
String? typeequipment;
TextEditingController nameprogramController = TextEditingController();
TextEditingController typeprogramController = TextEditingController();
TextEditingController typeequipmentController = TextEditingController();
File? image;
Future pickImage() async {
try {
final image = await ImagePicker().pickImage(source: ImageSource.gallery);
if (image == null) return;
final imageTemp = File(image.path);
setState(() => this.image = imageTemp);
} on PlatformException catch (e) {
print('Failed to pick image: $e');
}
}
@override
void initState() {
userId = FirebaseAuth.instance.currentUser!.uid;
FirebaseFirestore.instance
.collection("Users")
.doc(userId)
.get()
.then((value) {
var data = value.data() as Map<String, dynamic>;
nameprogram = data["nameprogram"];
typeprogram = data["typeprogram"];
typeequipment = data["typeequipment"];
// Populate TextEditingControllers with existing data
nameprogramController.text = nameprogram ?? '';
typeprogramController.text = typeprogram ?? '';
typeequipmentController.text = typeequipment ?? '';
});
super.initState();
}
@override
void dispose() {
// Dispose of the controllers when the widget is disposed
nameprogramController.dispose();
typeprogramController.dispose();
typeequipmentController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text(
'Workout Content',
style: TextStyle(fontWeight: FontWeight.bold, color: Colors.white),
),
centerTitle: true,
backgroundColor: Colors.black,
),
body: Padding(
padding: const EdgeInsets.all(18.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
height: 30,
),
Center(
child: Column(children: [
Text(
'Add details about your entire workout program',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15),
),
SizedBox(
height: 20,
),
TextField(
controller: nameprogramController,
decoration: InputDecoration(
hintText: "Name of the program",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(18),
borderSide: BorderSide.none),
fillColor: Colors.black.withOpacity(0.1),
filled: true,
),
),
SizedBox(
height: 20,
),
TextField(
controller: typeprogramController,
decoration: InputDecoration(
hintText: "Type of program(ex: strength, cardio, yoga",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(18),
borderSide: BorderSide.none),
fillColor: Colors.black.withOpacity(0.1),
filled: true,
),
),
SizedBox(
height: 20,
),
TextField(
controller: typeequipmentController,
decoration: InputDecoration(
hintText: "Type of equipment used",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(18),
borderSide: BorderSide.none),
fillColor: Colors.black.withOpacity(0.1),
filled: true,
),
),
SizedBox(
height: 20,
),
Container(
width: 250,
height: 70,
child: ElevatedButton(
onPressed: () {
pickImage();
},
style: ElevatedButton.styleFrom(
shape: const StadiumBorder(),
padding: const EdgeInsets.symmetric(vertical: 16),
backgroundColor: Colors.black,
),
child: const Text(
"+Add photo/video for cover",
style: TextStyle(fontSize: 15, color: Colors.white),
),
),
),
SizedBox(
height: 20,
),
Text(
'We suggest you to do a short video of 10-15 sec with some exercise that your program has so the user can get an idea of what to expect'),
SizedBox(
height: 40,
),
Container(
width: 250,
height: 70,
child: ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => WorkoutContentPage()),
);
},
style: ElevatedButton.styleFrom(
shape: const StadiumBorder(),
padding: const EdgeInsets.symmetric(vertical: 16),
backgroundColor: Colors.black,
),
child: const Text(
"Set price",
style: TextStyle(fontSize: 15, color: Colors.white),
),
),
),
]))
],
),
),
bottomNavigationBar: BottomAppBar(
color: const Color.fromARGB(255, 240, 240, 240),
child: Container(
width: 50,
child: ElevatedButton(
onPressed: () {
FirebaseFirestore.instance.collection("Users").doc(userId).set({
"nameprogram": nameprogramController.text,
"typeprogram": typeprogramController.text,
"typeequipment": typeequipmentController.text,
}).then((_) {
// Navigate to the user profile page
Navigator.push(
context,
MaterialPageRoute(builder: (context) => UserProfilePage()),
);
});
},
style: ElevatedButton.styleFrom(
shape: const StadiumBorder(),
padding: const EdgeInsets.symmetric(vertical: 16),
backgroundColor: Colors.black,
),
child: Text(
'Continue',
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
),
)),
),
),
);
// ignore: dead_code
}
void _alertNoText(BuildContext context) {
Alert(
context: context,
type: AlertType.warning,
title: "Post",
desc: "You have not written any text",
buttons: [
DialogButton(
onPressed: () => Navigator.pop(context),
width: 120,
child: const Text(
"Close",
style: TextStyle(color: Colors.white, fontSize: 20),
),
)
],
).show();
}
}
class UserProfilePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final userId = FirebaseAuth.instance.currentUser!.uid;
File? image;
return Scaffold(
appBar: AppBar(
title: const Text('User Profile'),
),
body: FutureBuilder<DocumentSnapshot<Map<String, dynamic>>>(
future:
FirebaseFirestore.instance.collection("Users").doc(userId).get(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: CircularProgressIndicator());
}
if (snapshot.hasError) {
return const Center(child: Text('Error fetching data'));
}
if (!snapshot.hasData || !snapshot.data!.exists) {
return const Center(child: Text('No data found'));
}
final data = snapshot.data!.data()!;
final nameprogram = data["nameprogram"];
final typeprogram = data["typeprogram"];
final typeequipment = data["typeequipment"];
return Padding(
padding: EdgeInsets.only(top: 20, left: 10, right: 10),
child: Container(
height: 135,
width: MediaQuery.of(context).size.width * 0.90,
decoration: ShapeDecoration(
shape: RoundedRectangleBorder(
borderRadius:
new BorderRadius.all(new Radius.circular(10))),
color: Colors.white,
shadows: [
BoxShadow(
color: Colors.grey.shade400,
blurRadius: 5,
spreadRadius: 2,
),
],
),
child: Row(mainAxisSize: MainAxisSize.min, children: [
SizedBox(
width: 10,
),
image != null
? Image.file(image!)
: Text("No image selected"),
const SizedBox(width: 10), // space between image & Column
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(
height: 25,
),
Text('$nameprogram',
style: TextStyle(fontWeight: FontWeight.bold)),
SizedBox(
height: 5,
),
Text('type: $typeprogram',
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.grey)),
SizedBox(
height: 5,
),
Text('equipment: $typeequipment',
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.grey)),
],
)),
])));
},
),
);
}
}