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 !!!!!!
CodePudding user response:
Change this onTap: widget.press()
to onTap:() => widget.press()
CodePudding user response:
The problem is here, the press() {}
. When you run this code, the page will run as soon as possible to navigate to your DetailsScreen().
RecomendedPlantCard(
country: "Russia",
image: "assets/images/image_1.png",
press: () {
Navigator.of(context).push(MaterialPageRoute(builder: (context) {
return const DetailsScreen();
}));
},
price: 448,
title: "Samantha",
),
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 .