This is my first page (RecomendsPlants) and I want to move to another page called (DetailsScreen)
RecomendsPlants:
// ignore_for_file: prefer_const_constructors
import 'package:flutter/material.dart';
import 'package:mr_plants_store/constants.dart';
import 'package:mr_plants_store/screens/details/details_screen.dart';
class RecomendsPlants extends StatefulWidget {
const RecomendsPlants({super.key});
@override
State createState() => _RecomendsPlantsState();
}
class _RecomendsPlantsState extends State {
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
RecomendedPlantCard(
country: "Russia",
image: "assets/images/image_1.png",
press: () {
Navigator.of(context).push(MaterialPageRoute(builder: (context) {
return const DetailsScreen();
}));
},
price: 448,
title: "Samantha",
),
RecomendedPlantCard(
country: "Russia",
image: "assets/images/image_2.png",
press: () {
Navigator.of(context).push(MaterialPageRoute(builder: (context) {
return const DetailsScreen();
}));
},
price: 448,
title: "Samantha",
),
RecomendedPlantCard(
country: "Russia",
image: "assets/images/image_3.png",
press: () {
Navigator.of(context).push(MaterialPageRoute(builder: (context) {
return const DetailsScreen();
}));
},
price: 448,
title: "Samantha",
),
],
),
);
}
}
class RecomendedPlantCard extends StatefulWidget {
const RecomendedPlantCard(
{super.key,
required this.image,
required this.title,
required this.country,
required this.price,
required this.press});
final String image, title, country;
final int price;
final Function press;
@override
State createState() => _RecomendedPlantCardState();
}
class _RecomendedPlantCardState extends State {
@override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return Container(
margin: EdgeInsets.only(
left: kDefaultPadding,
top: kDefaultPadding / 2,
bottom: kDefaultPadding,
),
width: size.width * 0.4,
child: Column(
children: [
Image.asset(widget.image),
GestureDetector(
onTap: widget.press(),
child: Container(
padding: EdgeInsets.all(kDefaultPadding / 2),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(10),
bottomRight: Radius.circular(10)),
boxShadow: [
BoxShadow(
offset: Offset(0, 10),
blurRadius: 10,
color: kPrimaryColor.withOpacity(0.1),
),
]),
child: Row(
children: [
RichText(
text: TextSpan(
children: [
TextSpan(
text: "${widget.title}\n".toUpperCase(),
style: Theme.of(context).textTheme.button,
),
TextSpan(
text: widget.country.toUpperCase(),
style: TextStyle(
color: kPrimaryColor.withOpacity(0.5),
),
),
],
),
),
Spacer(),
Text(
"$${widget.price}",
style: Theme.of(context)
.textTheme
.button
?.copyWith(color: kPrimaryColor),
),
],
),
),
)
],
),
);
}
}
DetailsScreen:
// ignore_for_file: prefer_const_constructors
import 'package:flutter/material.dart';
import 'package:mr_plants_store/screens/details/components/body.dart';
class DetailsScreen extends StatefulWidget {
const DetailsScreen({super.key});
@override
State createState() => _DetailsScreenState();
}
class _DetailsScreenState extends State {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Body(),
);
}
}
class Body extends StatefulWidget {
const Body({super.key});
@override
State createState() => _BodyState();
}
class _BodyState extends State {
@override
Widget build(BuildContext context) {
return Container(
child: Text("next Page"),
);
}
}
And I cant move to other page because of this Error:
════════ Exception caught by widgets library ═══════════════════════════════════
'package:flutter/src/widgets/navigator.dart': Failed assertion: line 4475 pos 12: '!_debugLocked': is not true.
package:flutter/…/widgets/navigator.dart:4475
The relevant error-causing widget was
RecomendedPlantCard
I tried all types of Navigator.of(context).push(MaterialPageRoute(builder: (context) {
return const DetailsScreen();
}));
but nothing work
I tried :
GestureDetector(
onTap: (){
Navigator.of(context).push(MaterialPageRoute(builder: (context) {
return const DetailsScreen();
}));
},
child:());
also not working
So Please help !!!!!!
2
Answers
Change this
onTap: widget.press()
toonTap:() => widget.press()
The problem is here, the
press() {}
. When you run this code, the page will run as soon as possible to navigate to your DetailsScreen().When you pass the callback
press: () { Navigator.of(context).push(MaterialPageRoute(builder: (context)=> const DetailsScreen())); }
to the RecomendedPlantCard widget and inside the build method, it will be called every time the RecomendsPlants or RecomendedPlantCard widget rebuilds.
Every time RecomendsPlants or RecomendedPlantCard widget rebuilds, the press callback will be called again which will try to push the same route again and again on the navigation stack. This can cause issues such as unexpected navigation behavior and memory leaks.
To fix this issue, you should move the logic of pushing the route outside the build method,
You can pass context and MaterialPageRoute inside the constructor of the RecomendedPlantCard and navigate inside the press method of _RecomendedPlantCardState .