我如何添加阴影的小部件像下面的图片?

这是我当前的小部件代码。


当前回答

如果你在小部件周围包上一张卡片,然后用抬高道具玩一点,也许就足够了。

我使用这个技巧使我的ListTile在列表中看起来更好。

对于你的代码,它可以是这样的:

return Card(
   elevation: 3, // PLAY WITH THIS VALUE 
   child: Row(
      crossAxisAlignment: CrossAxisAlignment.center,
      children: <Widget>[
         // ... MORE OF YOUR CODE 
      ],
   ),
);

其他回答

在开始使用这些答案之前,请查看Material Card小部件。它还允许你直接通过应用主题定义全局样式:

检查BoxShadow和BoxDecoration

Container可以带一个BoxDecoration(脱离你最初发布的代码),它带一个boxShadow

return Container(
  margin: EdgeInsets.only(left: 30, top: 100, right: 30, bottom: 50),
  height: double.infinity,
  width: double.infinity,
  decoration: BoxDecoration(
    color: Colors.white,
    borderRadius: BorderRadius.only(
      topLeft: Radius.circular(10),
        topRight: Radius.circular(10),
        bottomLeft: Radius.circular(10),
        bottomRight: Radius.circular(10)
    ),
    boxShadow: [
      BoxShadow(
        color: Colors.grey.withOpacity(0.5),
        spreadRadius: 5,
        blurRadius: 7,
        offset: Offset(0, 3), // changes position of shadow
      ),
    ],
  ),
)

The given answers do the trick for outer shadow i.e. around the widget. I wanted a shadow on the widget which is inside the boundaries and according to the github issue there is no inset attribute in ShadowBox yet. My workaround was to add a layer of widget with a gradient using the stack widget so that it looks like the widget itself has the shadows. You must use the mediaQuery for dimensions otherwise the layout will be messed up on different devices. Here's a sample of code for better understanding:

Stack(
            children: <Widget>[
              Container(
                decoration: BoxDecoration(
                  image: DecorationImage(
                    fit: BoxFit.cover,
                    image: AssetImage("assets/sampleFaces/makeup.jpeg"),
                    // fit: BoxFit.cover,
                  ),
                ),
                height: 350.0,
              ),
              Container(
                decoration: BoxDecoration(
                  gradient: LinearGradient(
                    begin: FractionalOffset.topCenter,
                    end: FractionalOffset.bottomCenter,
                    colors: [
                      Colors.black.withOpacity(0.0),
                      Colors.black54,
                    ],
                    stops: [0.95, 5.0],
                  ),
                ),
              )
            ],
          ),

使用BoxDecoration和BoxShadow。

下面是一个操作以下选项的可视化演示:

不透明度 x抵消 y抵消 模糊半径 扩散半径

动图在色彩方面做得不太好。你可以自己在设备上试试。

以下是演示的完整代码:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: ShadowDemo(),
      ),
    );
  }
}

class ShadowDemo extends StatefulWidget {
  @override
  _ShadowDemoState createState() => _ShadowDemoState();
}

class _ShadowDemoState extends State<ShadowDemo> {
  var _image = NetworkImage('https://placebear.com/300/300');

  var _opacity = 1.0;
  var _xOffset = 0.0;
  var _yOffset = 0.0;
  var _blurRadius = 0.0;
  var _spreadRadius = 0.0;

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        Center(
          child:
          Container(
            decoration: BoxDecoration(
              color: Color(0xFF0099EE),
              boxShadow: [
                BoxShadow(
                  color: Color.fromRGBO(0, 0, 0, _opacity),
                  offset: Offset(_xOffset, _yOffset),
                  blurRadius: _blurRadius,
                  spreadRadius: _spreadRadius,
                )
              ],
            ),
            child: Image(image:_image, width: 100, height: 100,),
          ),
        ),
        Align(
          alignment: Alignment.bottomCenter,
          child: Padding(
            padding: const EdgeInsets.only(bottom: 80.0),
            child: Column(
              children: <Widget>[
                Spacer(),
                Slider(
                  value: _opacity,
                  min: 0.0,
                  max: 1.0,
                  onChanged: (newValue) =>
                  {
                    setState(() => _opacity = newValue)
                  },
                ),
                Slider(
                  value: _xOffset,
                  min: -100,
                  max: 100,
                  onChanged: (newValue) =>
                  {
                    setState(() => _xOffset = newValue)
                  },
                ),
                Slider(
                  value: _yOffset,
                  min: -100,
                  max: 100,
                  onChanged: (newValue) =>
                  {
                    setState(() => _yOffset = newValue)
                  },
                ),
                Slider(
                  value: _blurRadius,
                  min: 0,
                  max: 100,
                  onChanged: (newValue) =>
                  {
                    setState(() => _blurRadius = newValue)
                  },
                ),
                Slider(
                  value: _spreadRadius,
                  min: 0,
                  max: 100,
                  onChanged: (newValue) =>
                  {
                    setState(() => _spreadRadius = newValue)
                  },
                ),
              ],
            ),
          ),
        )
      ],
    );
  }
}

在容器内使用shadowColor材质,如下所示:

Container(
  decoration: BoxDecoration(
      borderRadius: BorderRadius.only(
          bottomLeft: Radius.circular(10),
          bottomRight: Radius.circular(10)),
      boxShadow: [
        BoxShadow(
            color: Color(0xffA22447).withOpacity(.05),
            offset: Offset(0, 0),
            blurRadius: 20,
            spreadRadius: 3)
      ]),
  child: Material(
    borderRadius: BorderRadius.only(
        bottomLeft: Radius.circular(10),
        bottomRight: Radius.circular(10)),
    elevation: 5,
    shadowColor: Color(0xffA22447).withOpacity(.05),
    color: Color(0xFFF7F7F7),
    child: SizedBox(
      height: MediaQuery.of(context).size.height / 3,
    ),
  ),
)