pageBuilder 中的 setState 在 Flutter 中不起作用
setState in pageBuilder doesn't work in Flutter
我正在使用 Hero 小部件弹出一个 select 或页面,您可以在其中 select 您喜欢的颜色用作背景。
如果我点击“更改颜色!”然后主页面容器背景完全改变,但在 selector 页面上它仍然处于构建“状态”。
关闭并重新打开我的 select 或页面后,然后 - 当然 - 背景将充满漂亮的颜色...
有什么想法吗?
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,
)),
),
)
],
)),
);
}
}
用 Scaffold
小部件包裹您的 pageBuilder
的 Container
,它将解决问题。它只是与主要小部件重叠。
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;
});
},
NewWidget
是下一页
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
等待结果。当它弹出时,我们将从 NewWidget
获取当前状态并根据它更新 UI。
主页未更新,因为它来自不同的路径。
查看问题评论以了解有关 Difference between MaterialPageRoute and PageRouteBuilder
的更多信息
我正在使用 Hero 小部件弹出一个 select 或页面,您可以在其中 select 您喜欢的颜色用作背景。 如果我点击“更改颜色!”然后主页面容器背景完全改变,但在 selector 页面上它仍然处于构建“状态”。 关闭并重新打开我的 select 或页面后,然后 - 当然 - 背景将充满漂亮的颜色...
有什么想法吗?
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,
)),
),
)
],
)),
);
}
}
用 Scaffold
小部件包裹您的 pageBuilder
的 Container
,它将解决问题。它只是与主要小部件重叠。
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;
});
},
NewWidget
是下一页
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
等待结果。当它弹出时,我们将从 NewWidget
获取当前状态并根据它更新 UI。
主页未更新,因为它来自不同的路径。
查看问题评论以了解有关 Difference between MaterialPageRoute and PageRouteBuilder
的更多信息