Bhaskar Gupta
Bhaskar Gupta

Reputation: 41

Anchored Overlay not hiding after turning overlay to false? Flutter

I don't know why its not going even after changing the bool value to false.

Here is the code for overlay.

  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()),

                    );
                  },
                ),
              ),


            ],),

        );
      },
    );
  }
}

Here is the code for AnchoredOverlay for reference.

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;
  }
}

As soon I change the value of bool value, only the card hides and the not the button as shown below.

enter image description here

And here is the pic after changing the showoverlay value to false.

enter image description here

As you can see the button container is still not hidden so how can I solve this problem.

Please help and let me know if I am missing with any information in the question.

Upvotes: 1

Views: 1026

Answers (1)

John Oyekanmi
John Oyekanmi

Reputation: 386

You'll have to wrap the 'deselect' button in a setState Function and this will trigger the OverlayBuilder to rebuild.

do something of this such at the call to deselect the image:

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

Upvotes: 1

Related Questions