setState в pageBuilder не работает во Flutter
Я использую виджет Hero, чтобы открыть страницу выбора, где вы можете выбрать предпочитаемый цвет для использования в качестве фона. Если я нажму на "Изменить цвет!" тогда фон контейнера главной страницы отлично меняется, но на странице селектора он остается в «состоянии» сборки. После закрытия и повторного открытия моей страницы выбора, тогда, конечно, фон будет заполнен хорошим цветом...
Есть идеи?
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,
)),
),
)
],
)),
);
}
}
1 ответ
Оберните свой
pageBuilder
х
Container
с
Scaffold
виджет, это решит проблему. Он просто накладывается на основной виджет.
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(
Кроме того, есть еще одно решение
MaterialPageRoute
GestureDetector(
onTap: () async {
final result =
await Navigator.of(context).push(MaterialPageRoute(
builder: (context) => NewWidget(),
));
print("result isactNum0 $result");
setState(() {
actNum = result ? 1 : 0;
});
},
следующая страница
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
возвращается
future
и мы можем ждать результата. Пока он будет всплывать, мы получим текущее состояние от
NewWidget
и обновление пользовательского интерфейса на его основе.
Главная страница не обновлялась, потому что она с другого маршрута.
Проверьте комментарии к вопросу, чтобы узнать больше о различиях между MaterialPageRoute и PageRouteBuilder.