I'm trying to make it so that when you click on a picture, it changes to another. I tried doing this but it doesnt work-
class PopScreen extends StatefulWidget {
final int id;
const PopScreen({Key? key, required this.id}) : super(key: key);
@override
_PopScreenState createState() => _PopScreenState();
}
class _PopScreenState extends State<PopScreen> {
@override
Widget build(BuildContext context) {
String currentPath = normalPaths[widget.id];
return Scaffold(
appBar: AppBar(
backgroundColor: animalColorThemes[widget.id],
title: Text(
animalData[widget.id][0],
),
centerTitle: true,
),
body: GestureDetector(
onTap: () {
setState(() {
currentPath = activePaths[widget.id];
});
},
child: Stack(
children: [
Container(
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.fill,
image: AssetImage(
currentPath,
),
),
),
),
],
),
));
}
}
The image is based on the integer id that gets passed into this. The problem is probably that i'm doing normalPath[widget.id] before returning the widget, so when it set states, it turns into the normalPath right after turning into the activaPath. How i find my around around this?
CodePudding user response:
This happens because everytime you rebuild your widget, you set currentPath to normalPaths[widget.id] since you set currentPath = normalPaths[widget.id]; in the first line in your build method. To fix your issue you have to move currentPath outside the build method.
class _PopScreenState extends State<PopScreen> {
late String currentPath;
@override
void initState(){
currentPath = normalPaths[widget.id];
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: animalColorThemes[widget.id],
title: Text(
animalData[widget.id][0],
),
centerTitle: true,
),
body: GestureDetector(
onTap: () {
setState(() {
currentPath = activePaths[widget.id];
});
},
child: Stack(
children: [
Container(
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.fill,
image: AssetImage(
currentPath,
),
),
),
),
],
),
));
}
}
CodePudding user response:
TLDR; Declare currentPath in the class instead of the build method like so:
class _PopScreenState extends State<PopScreen> {
late String currentPath;
@override
void initState(){
currentPath = normalPaths[widget.id];
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: animalColorThemes[widget.id],
title: Text(
animalData[widget.id][0],
),
centerTitle: true,
),
body: GestureDetector(
onTap: () {
setState(() {
currentPath = activePaths[widget.id];
});
},
child: Stack(
children: [
Container(
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.fill,
image: AssetImage(
currentPath,
),
),
),
),
],
),
));
}
setState calls the build method and having currentPath = normalPaths[widget.id]; in the build method means, currentPath would be set to normalPaths[widget.id]; everytime setState is called.
So changing the scope of currentPath from the build method to the class would fix the issue.
