Flutter如何在任意孩子上使用boxShadow?

Posted

技术标签:

【中文标题】Flutter如何在任意孩子上使用boxShadow?【英文标题】:Flutter how to use boxShadow on arbitrary child? 【发布时间】:2020-10-10 12:33:10 【问题描述】:

我已经看到this 的问题,并且发生了奇怪的行为。


/// Case 1
Container(
  height: containerSize,
  width: containerSize,
  decoration: shadowBoxDecoration.copyWith(
    color: mainColor,
  ),
),

/// Case 2
Container(
  decoration: shadowBoxDecoration,
  child: Container(
    width: containerSize,
    height: containerSize,
    decoration: BoxDecoration(
      color: mainColor,
      borderRadius: borderRadius,
    ),
  ),
),

/// Case 3
Container(
  decoration: shadowBoxDecoration,
  child: FlatButton(
    textColor: mainColor,
    onPressed: () => ,
    shape: RoundedRectangleBorder(
      side: BorderSide(
        color: mainColor,
      ),
      borderRadius: borderRadius,
    ),
    child: Text('Test Text'),
  ),
),

我正在测试 3 种情况,在每种情况下我都以不同的方式应用阴影:

Case 1 将颜色内置到阴影样式中。

Case 2 是使用任何小部件的通用方法,在视觉上与Case 1 相同

Case 3Case 2FlatButtonchild

这就是我看到的

如您所见,FlatButton 的阴影似乎比必要的要大,我不明白如何才能让它发挥作用。

顶部和FlatButton 的按钮上可能有一些填充,但我无法调试它,因为小部件检查器只显示FlatButton(一些填充只是在视觉上存在)。

完整代码:


void main() 
  runApp(MyApp());


class MyApp extends StatelessWidget 
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) 
    return WidgetsApp(
        color: Colors.redAccent,
        builder: (context, child) 
          final boxShadow = [
            BoxShadow(
              color: Colors.grey.withOpacity(0.5),
              spreadRadius: 1,
              blurRadius: 1,
              offset: Offset(0, 3),
            ),
          ];

          final containerSize = 100.0;

          final borderRadius = BorderRadius.circular(10);

          final separator = Container(
            height: 50,
          );

          final mainColor = Colors.redAccent;

          final shadowBoxDecoration = BoxDecoration(
            borderRadius: borderRadius,
            boxShadow: boxShadow,
          );

          return Stack(
            children: [
              SizedBox.expand(
                child: Container(
                  color: Colors.white,
                ),
              ),
              SizedBox.expand(
                  child: Center(
                child: Column(
                  children: <Widget>[
                    // Spacing
                    separator,

                    /// Case 1
                    Container(
                      height: containerSize,
                      width: containerSize,
                      decoration: shadowBoxDecoration.copyWith(
                        color: mainColor,
                      ),
                    ),
                    // Spacing
                    separator,

                    /// Case 2
                    Container(
                      decoration: shadowBoxDecoration,
                      child: Container(
                        width: containerSize,
                        height: containerSize,
                        decoration: BoxDecoration(
                          color: mainColor,
                          borderRadius: borderRadius,
                        ),
                      ),
                    ),
                    separator,

                    /// Case 3
                    Container(
                      decoration: shadowBoxDecoration,
                      child: FlatButton(
                        textColor: mainColor,
                        onPressed: () => ,
                        shape: RoundedRectangleBorder(
                          side: BorderSide(
                            color: mainColor,
                          ),
                          borderRadius: borderRadius,
                        ),
                        child: Text('Test Text'),
                      ),
                    ),
                  ],
                ),
              )),
            ],
          );
        );
  



在低级别,我想要一个应用了阴影的按钮(并且还了解FlatButton 的特别之处)。

在更高的层次上,我想要一个Widget 可以将我的一般影子规则应用于任意孩子(我不明白为什么它不存在)。类似的东西:

class SimpleShadow extends StatelessWidget 
  final Widget child;

  const SimpleShadow(
    @required this.child,
  );

  @override
  Widget build(BuildContext context) 
    return Container(
      decoration: BoxDecoration(boxShadow: [
        BoxShadow(
          offset: Offset(0, 3),
          color: Colors.black.withOpacity(0.12),
          blurRadius: 0,
          spreadRadius: 0,
        ),
      ]),
      child: child,
    );
  

【问题讨论】:

您可以使用Material 小部件将阴影和其他类似效果添加到任意小部件,方法是将它们包装为child of Material 小部件。 感谢您的提示。 Material 似乎确实更容易(因为它只需要指定高度),但MaterialFlatButton 周围也有这个额外的填充。现在我需要找到一个支持适当阴影的按钮 当为“FlatButton”添加边框时,似乎“FlatButton”在容器内制作边框。那么你如何与 FlatButton 的外部容器接壤呢? 很高兴帮助@andras。试试RaisedButton 它预先构建了阴影和高程。 This 是对 Flutter 中可用 MaterialButtons 的引用。 【参考方案1】:

为“FlatButton”添加边框时,似乎“FlatButton”在容器内制作边框。那么你如何与 FlatButton 的外部容器接壤呢?

/// Case 3
                    Container(
                      decoration: BoxDecoration(
                        borderRadius: borderRadius,
                        boxShadow: boxShadow,
                        border: Border.all(
                          color: mainColor,
                          width: 2.0,
                          style: BorderStyle.solid,
                        ),
                      ),
                      child: FlatButton(
                        textColor: mainColor,
                        onPressed: () => ,
                        // shape: RoundedRectangleBorder(
                        //   side: BorderSide(
                        //     color: mainColor,
                        //   ),
                        //   borderRadius: borderRadius,
                        // ),
                        child: Text('Test Text'),
                      ),
                    ),

【讨论】:

这个暂时解决了这个问题,但是引入了其他几个:垂直填充太大且不可配置,InkWell仍然适用于较小的框,更不用说我想配置的困难整个按钮的背景。

以上是关于Flutter如何在任意孩子上使用boxShadow?的主要内容,如果未能解决你的问题,请参考以下文章

如何在任意逻辑状态图之间发送信号?

使文本在任意背景图像上可读

LLDB – 在任意对象的实例变量上设置观察点

在任意二进制文件的 MacOS 上更改进程名称

正则表达式中,如何在任意匹配字符后面加上原字符和特定内容

如何使用 asyncio 从使用 SubprocessProtocol 的子进程中读取并在任意点终止该子进程?