将覆盖设置为 false 后锚定覆盖不隐藏?扑

Anchored Overlay not hiding after turning overlay to false? Flutter

我不知道为什么即使将 bool 值更改为 false 后它仍然不运行。

这是覆盖的代码。

  int bools =1;
  @override
  Widget build(BuildContext context) {
    return  AnchoredOverlay(
      showOverlay: bools==1?true:false,

      child: Center(),
      overlayBuilder: (BuildContext context, Rect anchorBounds, Offset anchor) {
        return CenterAbout(
          position: anchor,
          child: Stack(
            children: [
              Transform(
                transform:
                Matrix4.translationValues(cardOffset.dx, cardOffset.dy, 0.0)
                  ..rotateZ(_rotation(anchorBounds)),
                origin: _rotationOrigin(anchorBounds),
                child:Container(
                  key: profileCardKey,
                  width: anchorBounds.width,
                  height: anchorBounds.height,
                  padding: EdgeInsets.only(top: 16,right: 16,left: 16,bottom: 60),
                  child: GestureDetector(
                    onPanStart: _onPanStart,
                    onPanUpdate: _onPanUpdate,
                    onPanEnd: _onPanEnd,
                    child: widget.card,
                  ),
                ),
              ),

              Positioned(
                bottom: 0,
                child: Arc(
                  arcType: ArcType.CONVEX,
                  edge: Edge.TOP,
                  height: 60.0,
                  child: BackdropFilter(
                    filter: ImageFilter.blur(sigmaX: 30, sigmaY: 30),
                    child: Container(
                      child: RawMaterialButton(
                        onPressed: () {
                          bools =0;
                          Navigator.pushNamed(context, ProfileView.profileView);
                        },
                      ),
                      height: 140,
                      width: MediaQuery.of(context).size.width,
                      color: Colors.white70.withOpacity(0),
                    ),
                  ),
                ),
              ),
              Positioned(
                left: 50,
                bottom: 60,
                child:  RawMaterialButton(

                  shape: CircleBorder(),
                  elevation: 100.0,
                  child: IconButton(
                    iconSize: 90,
                    onPressed: (){bools =0;},
                    icon:  Image.asset('images/deselect.png'),
                  ),
                  onPressed: (){bools =0;print(bools);},
                ),
              ),
              Positioned(
                right: 50,
                bottom: 60,
                child:  RawMaterialButton(

                  shape: CircleBorder(),
                  elevation: 100.0,
                  child: IconButton(
                    iconSize: 90,
                    onPressed: null,
                    icon:  Image.asset('images/select.png'),
                  ),
                  onPressed: () {
                    bools=1;
                    Navigator.push(
                      context,
                      MaterialPageRoute(
                          builder: (context) => ProfileView()),

                    );
                  },
                ),
              ),


            ],),

        );
      },
    );
  }
}

这里是AnchoredOverlay的代码,供参考。

class CenterAbout extends StatelessWidget {
  final Offset position;
  final Widget child;

  CenterAbout({
    key,
    this.position,
    this.child,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Positioned(
      left: position.dx,
      top: position.dy,
      child: FractionalTranslation(
        translation: Offset(-0.5, -0.5),
        child: child,
      ),
    );
  }
}

class AnchoredOverlay extends StatelessWidget {
  final bool showOverlay;
  final Widget Function(BuildContext, Rect anchorBounds, Offset anchor)
      overlayBuilder;
  final Widget child;

  AnchoredOverlay({
    key,
    this.showOverlay = false,
    this.overlayBuilder,
    this.child,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      // This LayoutBuilder gives us the opportunity to measure the above
      // Container to calculate the "anchor" point at its center.
      child: LayoutBuilder(
        builder: (BuildContext context, BoxConstraints constraints) {
          return OverlayBuilder(
            showOverlay: showOverlay,
            overlayBuilder: (BuildContext overlayContext) {
              // To calculate the "anchor" point we grab the render box of
              // our parent Container and then we find the center of that box.
              RenderBox box = context.findRenderObject() as RenderBox;
              final topLeft =
                  box.size.topLeft(box.localToGlobal(const Offset(0.0, 0.0)));
              final bottomRight = box.size
                  .bottomRight(box.localToGlobal(const Offset(0.0, 0.0)));
              final Rect anchorBounds = Rect.fromLTRB(
                topLeft.dx,
                topLeft.dy,
                bottomRight.dx,
                bottomRight.dy,
              );
              final anchorCenter = box.size.center(topLeft);

              return overlayBuilder(overlayContext, anchorBounds, anchorCenter);
            },
            child: child,
          );
        },
      ),
    );
  }
}

class OverlayBuilder extends StatefulWidget {
  final bool showOverlay;
  final Widget Function(BuildContext) overlayBuilder;
  final Widget child;

  OverlayBuilder({
    key,
    this.showOverlay = false,
    this.overlayBuilder,
    this.child,
  }) : super(key: key);

  @override
  _OverlayBuilderState createState() => new _OverlayBuilderState();
}

class _OverlayBuilderState extends State<OverlayBuilder> {
  OverlayEntry overlayEntry;

  @override
  void initState() {
    super.initState();

    if (widget.showOverlay) {
      WidgetsBinding.instance.addPostFrameCallback((_) => showOverlay());
    }
  }

  @override
  void didUpdateWidget(OverlayBuilder oldWidget) {
    super.didUpdateWidget(oldWidget);
    WidgetsBinding.instance.addPostFrameCallback((_) => syncWidgetAndOverlay());
  }

  @override
  void reassemble() {
    super.reassemble();
    WidgetsBinding.instance.addPostFrameCallback((_) => syncWidgetAndOverlay());
  }

  @override
  void dispose() {
    if (isShowingOverlay()) {
      hideOverlay();
      print("Hidden");
    }

    super.dispose();
  }

  bool isShowingOverlay() => overlayEntry != null;

  void showOverlay() {
    if (overlayEntry == null) {
      // Create the overlay.
      overlayEntry = OverlayEntry(
        builder: widget.overlayBuilder,
      );
      addToOverlay(overlayEntry);
    } else {
      // Rebuild overlay.
      buildOverlay();
    }
  }

  void addToOverlay(OverlayEntry entry) async {
    Overlay.of(context).insert(entry);
  }

  void hideOverlay() {
    if (overlayEntry != null) {
      overlayEntry.remove();
      overlayEntry = null;
    }
  }

  void syncWidgetAndOverlay() {
    if (isShowingOverlay() && !widget.showOverlay) {
      hideOverlay();
    } else if (!isShowingOverlay() && widget.showOverlay) {
      showOverlay();
    }
  }

  void buildOverlay() async {
    overlayEntry?.markNeedsBuild();
  }

  @override
  Widget build(BuildContext context) {
    WidgetsBinding.instance.addPostFrameCallback((_) => buildOverlay());

    return widget.child;
  }
}

当我改变 bool 值的值时,只有卡片隐藏而不是按钮,如下所示。

这是将 showoverlay 值更改为 false 后的图片。

如您所见,按钮容器仍然没有隐藏,我该如何解决这个问题。

如果我缺少问题中的任何信息,请帮助并告诉我。

您必须将 'deselect' 按钮包装在 setState 函数中,这将触发 OverlayBuilder 重建。

在取消选择图像的调用中执行以下操作:

void deselect() {
  // ... do somethings
  setState() {
    bools == 0;
    print(bool);
  }
  // do some other things
}