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

Posted

技术标签:

【中文标题】将覆盖设置为假后,锚定覆盖不隐藏?扑【英文标题】:Anchored Overlay not hiding after turning overlay to false? Flutter 【发布时间】:2021-06-14 22:18:51 【问题描述】:

我不知道为什么即使将 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 后的图片。

如您所见,按钮容器仍未隐藏,我该如何解决此问题。

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

【问题讨论】:

【参考方案1】:

您必须将“取消选择”按钮包装在 setState 函数中,这将触发 OverlayBuilder 重建。

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

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

【讨论】:

以上是关于将覆盖设置为假后,锚定覆盖不隐藏?扑的主要内容,如果未能解决你的问题,请参考以下文章

为啥这个覆盖查询的 indexOnly 属性为假

测试用例的编写

覆盖与隐藏!

如何在 C++ 中模拟覆盖父函数(不隐藏)?

C++重载隐藏和覆盖的区别

labview中制作一个选项卡按钮设置好背景,放入进去的控件怎么才能不被覆盖