Flutter是否支持负边距? [英] Does Flutter support negative margin?

查看:626
本文介绍了Flutter是否支持负边距?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通常不需要负边距,但在某些情况下它很有用.例如:为什么要使用负边距?

现在,当我将容器的边距设置为负值时,出现以下错误:

I/flutter ( 3173): 'package:flutter/src/widgets/container.dart': Failed assertion: line 251: 'margin == null ||
I/flutter ( 3173): margin.isNonNegative': is not true.

解决方案

要回答这个问题,您首先必须定义什么是负边距",或者实际上通常是边距".在CSS中,页边距在各种布局模型中具有各种含义,最常见的是,它们是有助于计算块布局模型用于放置后续子项的偏移量的几个值之一;在这种情况下,负的总边距仅表示下一个子项位于前一个子项的底部上方,而不是在其后.

在Flutter中,就像在CSS中一样,有几种布局模型;但是,当前没有与CSS块布局模型等效的小部件(它支持边距折叠,负边距,跳过浮点等).这样的布局模型当然可以实现,但尚未实现,至少不是在框架本身中实现.

要实现这样的布局模型,您将创建一个类似于RenderFlex或RenderListBody的RenderBox子代,可能提供一种使用ParentDataWidget设置每个子代的边距的方式,就像配置Flex子代的flex一样.使用扩展窗口小部件.

设计这样的新布局模型时,最复杂的部分可能是决定当子代太大或太小而无法适应传递给此新布局渲染对象的约束时,如何处理上溢或下溢.如果子项下溢,则RenderFlex渲染对象可以分配空间,如果子项下溢,则认为该错误(在调试模式下,该区域显示为黄色和黑色的条纹警告区域,并在控制台上记录一条消息) ;另一方面,RenderListBody渲染对象认为约束必须在主轴上是无界的,这意味着您基本上只能在列表内使用此布局模型(因此命名).

如果编写新的布局模型不吸引人,则可以使用允许子项重叠的现有布局小部件之一.堆栈是显而易见的选择,您可以在其中设置每个子项的显式位置,并且它们可以任意重叠(这与CSS绝对位置布局模型相似).另一个选项是CustomMultiChildLayout小部件,它使您可以依次布局和放置每个子级.这样,您可以将每个子项一个接一个地定位,通过将后一个子项的位置设置为从前一个子项的大小和位置得出的值来模拟负边距,但要使后一个子项的顶部在前一个子项的上方孩子的屁股.

如果对类似块的布局模型感兴趣,我们当然可以实现(请提交错误并描述您想要实现的模型,或者自己实现并发送拉取请求进行审查).不过,到目前为止,我们还没有发现它在实践中是否有用,至少不足以证明其复杂性.

Negative margin is generally not needed but there are situations where it’s really useful. For example: why use negative margins?

For now, when I set margin for a container to a negative value, I got the following error:

I/flutter ( 3173): 'package:flutter/src/widgets/container.dart': Failed assertion: line 251: 'margin == null ||
I/flutter ( 3173): margin.isNonNegative': is not true.

解决方案

To answer this question you first have to define what "negative margins", or really "margins" in general, really are. In CSS, margins have various meanings in the various layout models, most commonly, they are one of several values that contribute to computing the offset that the block layout model uses to place subsequent children; a negative total margin in this case merely means the next child is placed above the bottom of the previous child instead of after it.

In Flutter, as in CSS, there are several layout models; however, there is currently no widget that is equivalent to the CSS block layout model (which supports margin collapsing, negative margins, skipping floats, etc). Such a layout model could certainly be implemented, it just hasn't been implemented yet, at least not in the framework itself.

To implement such a layout model, you would create a RenderBox descendant similar to RenderFlex or RenderListBody, probably providing a way to set the margins of each child using a ParentDataWidget in the same way that Flex children can have their flex configured using the Expanded widget.

Probably the most complicated part of designing a new layout model like this would be deciding how to handle overflow or underflow, when the children are too big or too small to fit the constraints passed to this new layout render object. The RenderFlex render object has a way to distribute the space if the children underflow, and considers it an error if they overflow (in debug mode, this is shown by a yellow-and-black striped warning area and a message logged to the console); the RenderListBody render object on the other hand takes the view that the constraints must be unbounded in the main axis, which means you can basically only use this layout model inside a list (hence the name).

If writing a new layout model is not attractive, you could use one of the existing layout widgets that allow overlapping children. Stack is the obvious choice, where you set the explicit positions of each child and they can overlap arbitrarily (this is vaguely similar to the CSS absolute position layout model). Another option is the CustomMultiChildLayout widget, which lets you layout and position each child in turn. With this, you could position each child one after the other, simulating negative margins by setting the position of the subsequent child to a value that's derived from the size and position of the previous child, but such that the subsequent child's top is above the previous child's bottom.

If there's interest in a block-like layout model, we could certainly implement it (please file a bug and describe the model you'd like implemented, or, implement it yourself and send a pull request for review). So far, though, we've not found that it has been that useful in practice, at least not useful enough to justify the complexity.

这篇关于Flutter是否支持负边距?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆