【问题标题】:How to add shadow to ClipOval in flutter?如何在颤动中为 ClipOval 添加阴影?
【发布时间】:2020-10-05 17:18:52
【问题描述】:

作为初学者,我一直在尝试制作一个新应用。所以,给事物添加阴影对我来说是全新的。

所以,下面是我的代码:

Container(
          child: Row(
            mainAxisAlignment: MainAxisAlignment.start,
            children: <Widget>[
              ClipOval(
                child: Material(
                  color: Colors.white, // button color
                  child: InkWell(
                    // splashColor: Colors.red, // inkwell color
                    child: SizedBox(
                        width: 46, height: 46, child: Icon(Icons.menu,color: Colors.red,),),
                    onTap: () {},
                  ),
                ),
              ),

            ],
          ),
        ),

以下是模拟:

【问题讨论】:

  • 因为我不知道如何使用type 属性。你能举个例子吗,我可以试试。
  • child: Material( type: MaterialType.circle, clipBehavior: Clip.antiAlias, elevation: 4.0, color: Colors.white, child: InkWell( splashColor: Colors.orange, highlightColor: Colors.transparent, onTap: () {}, child: SizedBox( width: 46, height: 46, child: Icon(Icons.menu, color: Colors.red,), ), ), ),
  • 或者child: Container( width: 46, height: 46, decoration: ShapeDecoration( shape: CircleBorder(), shadows: [ BoxShadow(color: Colors.black, blurRadius: 4, offset: Offset(2, 2)), ], ), child: Material( shape: CircleBorder(), clipBehavior: Clip.antiAlias, color: Colors.white, child: InkWell( splashColor: Colors.orange, highlightColor: Colors.transparent, onTap: () {}, child: Icon(Icons.menu, color: Colors.red,), ), ), ),如果你想定义自己的影子
  • 当然这两个版本都没有使用任何ClipOval

标签: flutter flutter-layout


【解决方案1】:

为 ClipOval 添加阴影:

Center(
          child: Container(
            decoration: BoxDecoration(
              shape: BoxShape.circle,
              boxShadow: [
                BoxShadow(
                  color: Colors.green,
                  blurRadius: 50.0,
                  spreadRadius: 10.0,
                )
              ],
            ),
            child: ClipOval(
              child: Image.network(
                'https://i.picsum.photos/id/384/536/354.jpg?hmac=MCKw0mm4RrI3IrF4QicN8divENQ0QthnQp9PVjCGblo',
                width: 100,
                height: 100,
                fit: BoxFit.cover,
              ),
            ),
          ),
        ),

输出:

【讨论】:

    【解决方案2】:

    您可以创建自己的CustomClipper

    class CustomClipperOval extends CustomClipper<Rect> {
      @override
      Rect getClip(Size size) {
        return Rect.fromCircle(
            center: new Offset(size.width / 2, size.width / 2),
            radius: size.width / 2 + 3);
      }
    
      @override
      bool shouldReclip(CustomClipper<Rect> oldClipper) {
        return false;
      }
    }
    
    class ClipOvalShadow extends StatelessWidget {
      final Shadow shadow;
      final CustomClipper<Rect> clipper;
      final Widget child;
    
      ClipOvalShadow({
        @required this.shadow,
        @required this.clipper,
        @required this.child,
      });
    
      @override
      Widget build(BuildContext context) {
        return CustomPaint(
          painter: _ClipOvalShadowPainter(
            clipper: this.clipper,
            shadow: this.shadow,
          ),
          child: ClipRect(child: child, clipper: this.clipper),
        );
      }
    }
    
    class _ClipOvalShadowPainter extends CustomPainter {
      final Shadow shadow;
      final CustomClipper<Rect> clipper;
    
      _ClipOvalShadowPainter({@required this.shadow, @required this.clipper});
    
      @override
      void paint(Canvas canvas, Size size) {
        var paint = shadow.toPaint();
        var clipRect = clipper.getClip(size).shift(Offset(0, 0));
        canvas.drawOval(clipRect, paint);
      }
    
      @override
      bool shouldRepaint(CustomPainter oldDelegate) {
        return true;
      }
    }
    

    然后使用它

    ClipOvalShadow(
      shadow: Shadow(
        color: Colors.amber,
        offset: Offset(1.0, 1.0),
        blurRadius: 2,
      ),
      clipper: CustomClipperOval(),
      child: ClipOval(
        child: Material(
          color: Colors.white, // button color
          child: InkWell(
            // splashColor: Colors.red, // inkwell color
            child: Container(
              width: 46,
              height: 46,
              child: Icon(
                Icons.menu,
                color: Colors.black,
              ),
            ),
            onTap: () {},
          ),
        ),
      ),
    ),
    

    结果将是

    【讨论】:

    • 它没有达到预期的效果。加上使它的容器有另一个点击事件动画
    • 我的错误。我没有注意到您只需要 ClipOval 的阴影。您可以检查更新的答案。希望对你有帮助
    • 谢谢,伙计。我能知道你在哪里参考颤振教程或文档(显然不是官方文档)
    • 您的解决方案过于复杂:仅使用 Material.type 属性就足够了 - 请参阅原始问题下方的我的 cmets
    • "I wanted to respond to what the title says" - 因为这个问题是典型的XY Problem
    猜你喜欢
    • 2017-11-02
    • 2019-02-13
    • 2022-11-29
    • 2020-04-23
    • 2019-11-06
    • 1970-01-01
    • 1970-01-01
    • 2014-10-10
    • 1970-01-01
    相关资源
    最近更新 更多