容器小部件内无法应用边框半径

65

在子Container内不适用边框半径。尝试使用SizedBoxStack小部件。我需要在容器内看到边框。

Scaffold(
  appBar: AppBar(
    title: new Text("ListView"),
  ),
  body: Center(
      child: Padding(
        padding: EdgeInsets.all(15.0),
        child: Container(
            decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(15.0),
                border: Border.all(
                    color: Colors.green,
                    width: 2.0
                )
            ),
            child: Container(
              color: Colors.red,
            )
        ),
      )
  )
)

10个回答

65

其他答案已经说明了您需要使用ClipRRect将边框半径应用于Container小部件的子组件。

然而,Container小部件现在具有其clipBehaviour属性来剪切其子组件:

Container(
  // Add the line below
  clipBehavior: Clip.hardEdge,
  decoration: BoxDecoration(
    borderRadius: BorderRadius.circular(15.0),
    border: Border.all(color: Colors.green, width: 2.0)),
  child: Container(
    color: Colors.red,
  ),
);

使用此属性而不是嵌套小部件是良好的实践,以获得清晰的代码。


4
这应该被接受为答案。 - iStar
3
使用ClipRRect更加占用处理器资源,因此这是最佳答案。 - Maruf Hassan
非常感谢您的完美回答。您无法将boxShadow添加到ClipRRect的装饰器中,它不起作用。但是,您可以将该boxShadow添加到具有clipBehavior Clip.hardEdge的容器中。这也是为什么应该接受这个答案的另一个原因。 - Johan Witters
你很棒! - Hamid Hussainy

63

试试这个, 使用 ClipRRect 并将其嵌套在另一个 Container 中,现在您可以添加 非均匀边框

Container(
                    decoration: BoxDecoration(
                      color: Colors.white,
                      borderRadius: BorderRadius.circular(10),
                      boxShadow: [BoxShadow(color: Colors.black12, blurRadius: 5)],
                    ),
                    child: ClipRRect(
                      borderRadius: BorderRadius.circular(10),
                      child: Container(
                        padding: EdgeInsets.all(20),
                        decoration: BoxDecoration(
                          border: Border(
                            left: BorderSide(color: Colors.indigo, width: 5),
                          ),
                        ),
                        child: Column(
                          mainAxisSize: MainAxisSize.min,
                          children: <Widget>[
                            Icon(Icons.home),
                            Text("Home"),
                          ],
                        ),
                      ),
                    ),
                  )

28

decoration 是绘制在子元素后面的。如果你希望装饰物被应用在容器的子元素前面,请使用 foregroundDecoration

Scaffold(
  appBar: AppBar(
    title: new Text("ListView"),
  ),
  body: Center(
      child: Padding(
        padding: EdgeInsets.all(15.0),
        child: Container(
            foregroundDecoration: BoxDecoration(
                borderRadius: BorderRadius.circular(15.0),
                border: Border.all(
                    color: Colors.green,
                    width: 2.0
                )
            ),
            child: Container(
              color: Colors.red,
            )
        ),
      )
  )
)

上述代码在子容器前绘制边框。请注意,即使使用 foregroundDecoration,子容器仍将具有锐利的角。

如果您希望子容器拥有圆角,则需要为子容器应用 borderRadius 或者使用与父容器相同的边框半径来使用 ClipRRect


19

使用

ClipRRect

替代

Container

widget。

之前的代码(无法运行):

 Center(
        child: Container(
          decoration: BoxDecoration(
            borderRadius: _getAllRoundedBorderRadius(),
          ),
          child: Hero(
            tag: "CossackHero",
            child: TweenImage(
              last: AssetImage("images/background/cossack_0.jpg"),
              first: AssetImage("images/background/c_cossack_0.jpg"),
              duration: 2,
              height: height,
            ),
          ),
        ),
      ),

之后:

Center(
        child: ClipRRect(
          borderRadius: getAllRoundedBorderRadius(),
          child: Hero(
            tag: "CossackHero",
            child: TweenImage(
              last: AssetImage("images/background/cossack_0.jpg"),
              first: AssetImage("images/background/c_cossack_0.jpg"),
              duration: 2,
              height: height,
            ),
          ),
        ),
      ),

8
const innerRadius = 15.0;
const borderWidth = 2.0;
const borderColor = Colors.green;
const color = Colors.red;
const size = 100.0;

Container(
  decoration: BoxDecoration(
    borderRadius: BorderRadius.circular(innerRadius + borderWidth),
    color: borderColor,
  ),
  padding: EdgeInsets.all(borderWidth),
  child: ClipRRect(
    borderRadius: BorderRadius.circular(innerRadius),
    child: Container(
      color: color,
      width: size,
      height: size,
    ),
  ),
);

这是其外观:

enter image description here

以下是其工作原理:https://codepen.io/mshibanami/pen/LYyQJXa


顺便说一下,有些答案建议您使用一个包含bordercolordecorationContainer来实现此效果:

Container(
  width: size,
  height: size,
  decoration: BoxDecoration(
    borderRadius: BorderRadius.circular(innerRadius),
    border: Border.all(
      color: borderColor,
      width: borderWidth,
    ),
    color: color,
  ),
)

这样做可以,但并不理想,因为内部颜色似乎略微超出边框。所以当边框接近背景颜色时,可能会像这样突出:

输入图片说明


7

截图:

这里输入图片描述


使用ClipRRect实现(使用2个Container):

ClipRRect(
  borderRadius: BorderRadius.circular(16),
  child: Container(
    width: 100,
    height: 100,
    color: Colors.black,
    child: Container(
      margin: EdgeInsets.all(8),
      color: Colors.blue,
    ),
  ),
)
没有 ClipRRect (使用1个 Container)
Container(
  width: 100,
  height: 100,
  decoration: BoxDecoration(
    borderRadius: BorderRadius.circular(16),
    border: Border.all(
      color: Colors.black,
      width: 4,
    ),
    color: Colors.blue,
  ),
)

1
ClipRRect与borderRadius结合起来是我找到的最佳解决方案,非常感谢 :) - g4s0l1n

5

请使用以下代码替换原有代码

Scaffold(
appBar: AppBar(
title: new Text("ListView"),
),
body: Center(
  child: Padding(
    padding: EdgeInsets.all(15.0),
    child: Container(
        decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(15.0),
            border: Border.all(
                color: Colors.green,
                width: 2.0
            )
        ),
        child: Container(
              decoration: new BoxDecoration(borderRadius: 
        BorderRadius.circular(15.0),
                        color: Colors.red,),
                    )
    ),
  )
)
)

已经将边框定义为父容器。在子容器中再次添加是否必要?@Zulfiqar - NIRAV PATEL
BorderRadius属性定义了小部件的形状,而不是围绕它的线条。如果您在父小部件上使用borderRadius,则子代不会继承该属性,因此它将以默认的矩形形状绘制。如果您希望它具有圆角边框,您也必须指定它。 - Iule

3

尝试

decoration: BoxDecoration(
                              gradient: new LinearGradient(
                                begin: Alignment.topCenter,
                                end: Alignment.bottomCenter,
                                stops: [0.02, 0.02],
                                colors: [Colors.red, Colors.white],
                              ),
                              borderRadius: BorderRadius.all(Radius.circular(10)),
                              color: Colors.white,
                              boxShadow: [
                                BoxShadow(color: Colors.grey, blurRadius: 5.0),
                              ],
                            ),

为什么要使用梯度,以及这如何回答这个问题? - Iule

2

你只需要添加这行代码 clipBehavior:Clip.hardEdge,

Scaffold(
  appBar: AppBar(
    title: new Text("ListView"),
  ),
  body: Center(
      child: Padding(
        padding: EdgeInsets.all(15.0),
        child: Container(
            

clipBehavior:Clip.hardEdge,

            decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(15.0),
                border: Border.all(
                    color: Colors.green,
                    width: 2.0
                )
            ),
            child: Container(
              color: Colors.red,
            )
        ),
      )
  )
)

0

我猜你的容器可能是因为没有子元素/高度/宽度而不可见。

尝试添加一些文本作为子元素,或者如果您想要扩展它,可以使用SizedBox.expand进行强制。

有关边框示例,请参见此答案


边框可见。子小部件的边框半径存在问题。这是图像链接http://putul.io/JWDFnTYTl。在子小部件中未应用父小部件的边框,即我提供的那个。@MarcinSzałek - NIRAV PATEL

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接