将覆盖设置为假后,锚定覆盖不隐藏?扑
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
【讨论】:
以上是关于将覆盖设置为假后,锚定覆盖不隐藏?扑的主要内容,如果未能解决你的问题,请参考以下文章