如何修复可取消小部件的边框?

11
我有一个问题,关于截图中标记的可消除边框。

https://imgur.com/a/Jv0sdi2

return Dismissible(
    child: Container(
        height: 256,
        decoration: ShapeDecoration(
            shape: RoundedRectangleBorder(
                borderRadius: new BorderRadius.circular(20.0)
            )
        )
    );
);

嗨,kotan37,你能添加一段代码片段吗? - dumazy
是的,我添加了代码。 - kotan37
只需将右上角的边框半径设置为0,而不是20。通常情况下,如果您花时间弄清楚自己要做什么,而不是发布截图并期望其他人解决问题,那么您会更加幸运。请参见:https://api.flutter.dev/flutter/painting/BorderRadius-class.html - Omn
@Omn 显然不是他想要做的 - 圆角应该保留,背景应该填充为红色。 - Hannes Hertach
7个回答

12
我找到了一个解决方案。将可滑动组件(Dismissible)用ClipRRect组件包装,然后从子组件中删除borderRadius。只有ClipRRect应该有borderRadius。
ClipRRect(
  borderRadius: BorderRadius.circular(15.0),
  child: Dismissible(
    child: YourWidgetContainer();
 )
)

enter image description here


7

当我尝试使用圆角时,我遇到了相同的问题。

最终一个小技巧解决了这个问题。

不要在Dismissible中设置background,而是创建一个Stack并将背景小部件放在Dismissible后面。

Stack(
  overflow: Overflow.clip,
  children: <Widget>[
    MyBackgroundWidget(), // instead of background
    Dismissible(
      child: MyForegroundWidget(),
      // no background
    )
  ],
);

这种方法可以工作,但你会失去折叠动画效果。你也注意到了吗? - baby.zard
您可以使用onResize回调手动控制背景退出动画。只需根据在onResize方法中更改的布尔变量配置一些动画即可。 - siega

5
问题是dismissible.dart文件中的裁剪行为。 我已经通过编辑Dismissible类本身来解决了这个问题。在559-573行,你会发现一个if语句,看起来像这样:
if (background != null) {
      content = Stack(children: <Widget>[
        if (!_moveAnimation.isDismissed)
          Positioned.fill(
            child: ClipRect(
              clipper: _DismissibleClipper(
                axis: _directionIsXAxis ? Axis.horizontal : Axis.vertical,
                moveAnimation: _moveAnimation,
              ),
              child: background,
            ),
          ),
        content,
      ]);
    }

如果您只是在ClipRect中注释掉clipper属性,背景将会变成透明的,您将不会失去折叠动画。

0

现在已经是2021年了,但我仍未找到任何关于此问题的可靠解决方案。

因此,我通过修改Dismissiable widget包并向AnimationController添加Listener来检查子项是否正在移动,成功地删除了ClipRect。我对result感到非常满意。

您可以按照以下步骤操作:

第一步:

打开Dismissable widget并定义一个clipBackground布尔值,然后在第616行之前添加以下代码:if (background != null)

    // Adding a Listener
    _moveAnimation.addListener(() {
      if (_moveController!.isDismissed) {
        setState(() {
          clipBackground = true;
        });
      }
      if (_moveController!.isCompleted) {
        setState(() {
          clipBackground = true;
        });
      }
      // if child stop moving
      if (_moveController!.value == 0) {
        setState(() {
          clipBackground = true;
        });
      }
      //If child is moving
      if (_moveController!.value != 0) {
        setState(() {
          clipBackground = false;
        });
      }
    });

你可以使用 OR 运算符 || 来使代码更简短。

第二步:

修改代码,将 if (background != null) 改为三元运算符,如下所示:

if (background != null) {
      content = Stack(children: <Widget>[
        if (!_moveAnimation.isDismissed)
          Positioned.fill(
            child: ClipRect(
              //If true add a ClipRect to the widget
              clipper: clipBackground!
                  ? _DismissibleClipper(
                      axis: _directionIsXAxis ? Axis.horizontal : Axis.vertical,
                      moveAnimation: _moveAnimation,
                    )
                  : null,
              child: background,
            ),
          ),
        content,
      ]);
    }


0

我也遇到了同样的问题,经过很多定制,我发现最好的解决方案是使用以下包:flutter_slidable。链接将带您浏览它提供的选项。我喜欢它!


0

作为解决方法,您可以尝试使用以下方法:

  1. 将您的 Dismissible 用 ClipRRect 包装,并为其提供适当的 borderRadius,作为您的 Dismissible 的子元素
  2. 将您的 Dismissible 的子元素包装在额外的 Container 中,并使用从左到右的 LinearGradient 为其着色,颜色为 Dismissible 的两个背景颜色。

在 DartPad 上查看使用此解决方法的示例:https://dartpad.dev/7224dd055bc7bdc73ab6eb66002db104

我仍然看到可能会出现一些问题,这取决于 Dismissible 背景中的内容,但在大多数情况下,这应该是有效的。

解决方法示例


0

那样做不起作用,因为您正在给整个容器添加边框,而应该使用BorderRadius.only

  return Dismissible(
  key: UniqueKey(),
  child: Container(
    height: 256,
    decoration: ShapeDecoration(
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.only(
            topLeft: Radius.circular(20),
            bottomLeft: Radius.circular(20.0)),
      ),
    ),
  ),
);

现在,您可以具体选择要提供边框的哪一侧。


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