Flutter是否支持负保证金?

Wei*_*ong 18 flutter

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

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

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

Pra*_*yan 50

容器具有有用的转换属性。

在此处输入图片说明

child: Container(
  color: Theme.of(context).accentColor,
  transform: Matrix4.translationValues(0.0, -50.0, 0.0),
),
Run Code Online (Sandbox Code Playgroud)

  • 有没有办法删除转换后的小部件留下的底部边距? (4认同)
  • 哇,这真的对我有帮助! (2认同)
  • 有没有办法将后一个容器的上边距置于前一个容器的后面? (2认同)

leg*_*ael 28

要扩展接受的答案,您可以用 包装任何小部件Transform.translate。它需要一个简单的Offset参数。

我发现它比翻译矩阵更容易使用。

Transform.translate(
   // e.g: vertical negative margin
   offset: const Offset(-10, 0),
   child: ...
),
Run Code Online (Sandbox Code Playgroud)


Ant*_*onB 11

我要给出答案,主要是因为我必须找到一种方法来做到这一点。

我想说这不是理想的,可能可以通过更好的方式来实现,但是确实可以达到预期的效果。

如您所见,可以使用堆栈将文本否定地拉到其父外部:在此处输入图片说明

Container(
  constraints: BoxConstraints.loose(Size.fromHeight(60.0)),
  decoration: BoxDecoration(color: Colors.black), 
  child: 
    Stack(
      alignment: Alignment.topCenter,
      overflow: Overflow.visible,
      children: [
        Positioned(
          top: 10.0,
          left: -15.0,
          right: -15.0,
          child: Text("OUTSIDE CONTAINER", style: TextStyle(color: Colors.red, fontSize: 24.0),)
        )
      ]
    )
)
Run Code Online (Sandbox Code Playgroud)


Fab*_*ese 7

简短的回答是"不,它没有".

为了提供更多细节,Flutter有一个复杂但有效的算法来渲染其小部件.在运行时分析边距和填充,并确定窗口小部件的最终大小和位置.当您尝试发出负边距时,您有意创建一个非valide布局,其中窗口小部件以某种方式从它应占用的空间中退出.

考虑在这里阅读文档.

无论如何,我相信你应该在另一个线程中更好地表达问题,并真正问一个解决方案,你正试图用那些负边缘来实现这个行为.我相信你会得到更多这样的方式.

干杯


Ian*_*son 7

要回答这个问题,首先要确定一般的"负利润率"或真正的"利润率".在CSS中,边距在各种布局模型中具有不同的含义,最常见的是,它们是有助于计算块布局模型用于放置后续子节点的偏移量的若干值之一; 在这种情况下,负的总保证金仅仅意味着下一个孩子被放置在前一个孩子的底部之上而不是之后.

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

要实现这样的布局模型,您可以创建一个类似于RenderFlex或RenderListBody的RenderBox后代,可能提供一种使用ParentDataWidget设置每个子节点边距的方法,就像Flex子节点可以flex使用Expanded小部件配置它们一样.

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

如果编写新的布局模型不具吸引力,则可以使用允许重叠子项的现有布局小部件之一.Stack是显而易见的选择,您可以在其中设置每个子项的显式位置,并且它们可以任意重叠(这与CSS绝对位置布局模型模糊地相似).另一个选项是CustomMultiChildLayout小部件,它允许您依次布局和定位每个子节点.有了这个,你可以一个接一个地定位每个孩子,通过将后续孩子的位置设置为从前一个孩子的大小和位置得到的值来模拟负边距,但是这样后续孩子的顶部高于前一个孩子的孩子的底部.

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


Sar*_*rma 5

不,Flutter 不允许负边距,但以防万一您仍然希望小部件相互重叠,您可以使用带有 Positioned 的 Stack,这将允许您生成可以使用负边距进行的布局。

这是一个例子:

import 'package:flutter/material.dart';

class MyHomePage extends StatefulWidget {
  MyHomePageState createState() => new MyHomePageState();
}

class MyHomePageState extends State<MyHomePage>  {


  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        body: new Center(
          child: new Container(
            padding: const EdgeInsets.all(8.0),
            height: 500.0,
            width: 500.0,
            child: new Stack(
              overflow: Overflow.visible,
              children: <Widget>[
                new Icon(Icons.pages, size: 36.0, color: Colors.red),
                new Positioned(
                  left: 20.0,
                  child: new Icon(Icons.pages, size: 36.0, color: Colors.green),
                ),

              ],
            ),
          ),
    )
    );
  }
}

void main() {
  runApp(new MaterialApp(
    title: 'Flutter Demo',
    theme: new ThemeData(
      primarySwatch: Colors.deepPurple,
    ),
    home: new MyHomePage(),
  ));
}
Run Code Online (Sandbox Code Playgroud)

这将导致:

截屏

注意:您还可以在“定位小部件”中给出负值。


Tom*_*ero 5

您可以使用OverflowBox来忽略某些约束。

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Container(
          color: Colors.blue.shade300,
          child: Padding(
            padding: const EdgeInsets.all(20),
            child: Column(
              children: [
                Expanded(
                  child: Container(
                    color: Colors.white,
                    child: Center(
                      child: Text('Padding on this one.'),
                    ),
                  ),
                ),
                SizedBox(height: 20),
                Expanded(
                  child: OverflowBox(
                    maxWidth: MediaQuery.of(context).size.width,
                    child: Container(
                      color: Colors.red.shade300,
                      child: Center(
                        child: Text('No padding on this one!'),
                      ),
                    ),
                  ),
                ),
                SizedBox(height: 20),
                Expanded(
                  child: Container(
                    color: Colors.yellow.shade300,
                    child: Center(
                      child: Text('Look, padding is back!'),
                    ),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
Run Code Online (Sandbox Code Playgroud)

结果:

在此输入图像描述