I'm using Hero widget to pop up a selector page where you can select your preferred color to use as background. If I tap on "Change color!" then the main page container background changes perfectly, but on the selector page it remains in the build "state". After closing and reopening my selector page, then - of course - the background will filled with the good color...
Any idea?
import 'package:flutter/cupertino.dart';
import 'dart:ui';
class TestPage extends StatefulWidget {
@override
_TestPageState createState() => _TestPageState();
}
class CustomRectTween extends RectTween {
final Rect? begin;
final Rect? end;
CustomRectTween({
required this.begin,
required this.end,
}) : super(begin: begin, end: end);
@override
Rect lerp(double t) {
final elasticCurveValue = Curves.easeOut.transform(t);
double? xLeft = begin!.left;
double yLeft = end!.left;
double xRight = begin!.right;
double yRight = end!.right;
double xTop = begin!.top;
double yTop = end!.top;
double xBottom = begin!.bottom;
double yBottom = end!.bottom;
return Rect.fromLTRB(
lerpDouble(xLeft, yLeft, elasticCurveValue)!,
lerpDouble(xTop, yTop, elasticCurveValue)!,
lerpDouble(xRight, yRight, elasticCurveValue)!,
lerpDouble(xBottom, yBottom, elasticCurveValue)!,
);
}
}
class _TestPageState extends State<TestPage> {
int actNum = 1;
@override
void initState() {
// initState vagyis itt kerülnek beállításra az alapértékek
super.initState();
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: Stack(
children: [
Container(
color: actNum == 1 ? Colors.greenAccent : Colors.white,
child: Hero(
tag: "akcio",
transitionOnUserGestures: true,
createRectTween: (begin, end) {
return CustomRectTween(begin: begin, end: end);
},
child: GestureDetector(
onTap: () {
Navigator.of(context).push(new PageRouteBuilder(
opaque: false,
maintainState: false,
barrierDismissible: false,
transitionDuration: Duration(milliseconds: 450),
pageBuilder: (BuildContext context, _, __) {
return Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: Stack(
children: [
Positioned(
bottom: 100.0,
child: Hero(
tag: "akcio",
child: GestureDetector(
onDoubleTap: () {
Navigator.of(context).pop();
},
onTap: () {
if (actNum == 1) {
actNum = 0;
} else {
actNum = 1;
}
setState(() {});
},
child: Container(
height: 100.0,
width:
MediaQuery.of(context).size.width,
color: actNum == 1
? Colors.greenAccent
: Colors.white,
child: Container(
child: Text('Change color!')),
),
),
),
)
],
),
);
}));
},
child: Icon(
Icons.play_circle_fill,
color: Colors.black,
size: 75.0,
)),
),
)
],
)),
);
}
}
CodePudding user response:
Wrap your pageBuilder
's Container
with Scaffold
widget, it will solve the issue. It is just overlaying with main widget.
transitionDuration: Duration(milliseconds: 450),
pageBuilder: (BuildContext context, _, __) {
return Scaffold(
body: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: Stack(
Also, another solution is MaterialPageRoute
GestureDetector(
onTap: () async {
final result =
await Navigator.of(context).push(MaterialPageRoute(
builder: (context) => NewWidget(),
));
print("result isactNum0 $result");
setState(() {
actNum = result ? 1 : 0;
});
},
NewWidget
is the nextPage
class NewWidget extends StatefulWidget {
const NewWidget({Key? key}) : super(key: key);
@override
State<NewWidget> createState() => _NewWidgetState();
}
class _NewWidgetState extends State<NewWidget> {
bool isactNum0 = true;
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.transparent,
body: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: Stack(
children: [
Positioned(
bottom: 100.0,
child: Hero(
tag: "akcio",
child: GestureDetector(
onDoubleTap: () {
Navigator.of(context).pop(isactNum0); // pass current state isactNum0
},
onTap: () {
setState(() {
isactNum0 = !isactNum0;
});
},
child: Container(
height: 100.0,
width: MediaQuery.of(context).size.width,
color: isactNum0 ? Colors.greenAccent : Colors.white,
child: Container(child: Text('Change color!')),
),
),
),
)
],
),
),
);
}
}
push
returns future
and we can wait for result. While it will pop, we will get current state from NewWidget
and updating UI based on it.
Main page wasn't updating because it is from different route.
Check question comments to learn more about Difference between MaterialPageRoute and PageRouteBuilder