【问题标题】:How to fix this dismissible widget border如何修复这个可关闭的小部件边框
【发布时间】:2023-03-05 06:24:02
【问题描述】:

我对屏幕截图上标记的可关闭边框有疑问

https://imgur.com/a/Jv0sdi2

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

【问题讨论】:

  • 嗨 kotan37,你能添加一个代码 sn-p 吗?
  • 是的,我添加了代码
  • 只需将右上角的边框半径设置为 0 而不是 20。通常,如果您花时间弄清楚您正在尝试做什么而不是发布屏幕截图并期待其他人来弄清楚。见:api.flutter.dev/flutter/painting/BorderRadius-class.html
  • @Omn 这显然不是他想要做的——角落半径应该保持不变,背景应该被填充为红色。

标签: flutter dart


【解决方案1】:

我在尝试圆角时遇到了同样的问题。

最终,一个小变通办法奏效了。

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

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

【讨论】:

  • 这有点工作,但你失去了折叠动画。你也注意到了吗?
  • 您可以手动控制背景退出动画,使用 onResize 回调。只需根据 onResize 方法中更改的布尔变量配置一些动画。
【解决方案2】:

问题是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-property,背景会是透明的,不会丢失折叠动画。

【讨论】:

    【解决方案3】:

    我找到了解决方案。用 ClipRRect 小部件包裹 Dismissible 小部件,并从子小部件中移除borderRadius。只有 ClipRRect 应该有borderRadius。

    ClipRRect(
      borderRadius: BorderRadius.circular(15.0),
      child: Dismissible(
        child: YourWidgetContainer();
     )
    )
    

    【讨论】:

      【解决方案4】:

      这行不通,因为你给整个容器提供了边框,你应该使用 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)),
            ),
          ),
        ),
      );
      

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

      【讨论】:

        【解决方案5】:

        我也遇到了同样的问题,通过大量自定义找到的最佳解决方案是以下包:flutter_slidable。该链接会将您导航到它提供的选项。我喜欢那个!

        【讨论】:

          【解决方案6】:

          作为一种解决方法,您可以尝试使用这种方法:

          1. 用 ClipRRect 包装你的 Dismissible 并给它一些适当的边框半径,作为你 Dismissible 的子级
          2. 将 Dismissible 的子元素包裹在一个额外的 Container 中,并使用 Dismissible 的两个背景颜色从左到右为其赋予 LinearGradient 的颜色。

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

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

          Workaround example

          【讨论】:

            【解决方案7】:

            现在是 2021 年,我仍然没有找到任何可靠的解决方法。

            所以我可以通过修改Dismissiable widget 包并在AnimationController 中添加Listener 来检查孩子是否真的在移动,从而在Dismissiable widget 的孩子移动时删除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,
                  ]);
                }
            
            

            【讨论】:

              猜你喜欢
              • 2020-02-04
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-11-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多