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 小部件包裹您的 pageBuilderContainer,它将解决问题。它只是与主要小部件重叠。

  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

的更多信息