如何将阴影框扩展到容器之外

How to expand a shadow box beyond the container

我正在创建一个带有投射阴影的卡片的水平卷轴。

我不明白为什么如果我有 3 张卡片阴影会被“剪裁”,但如果我有 2 张卡片则不会。

它应该是这样的:

这是当我有 3 个或更多元素时的样子(我怀疑元素比适合屏幕的元素多)。

如何避免这种行为?

我在 SingleChildScrollView 中有一个列。在该列中,有带有卡片行的 SingleChildScrollViews。

这是脚手架里面的代码:

SingleChildScrollView(
    physics: const BouncingScrollPhysics(),
    child: Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        const SectionTitlePadded("Dependency"),
        SingleChildScrollView(
          physics: const BouncingScrollPhysics(),
          scrollDirection: Axis.horizontal,
          child: Row(children: [
            SizedBox(width: CustomTheme.standardHorizontalPadding.left * 0.7),
            TaskRejectionReasonCard(onButtonPressed: () => rejectWithReason(Reason.Location), buttonText: "Location", explanation: "A specific location is required", image: Image.asset("assets/images/location.png")),
            TaskRejectionReasonCard(onButtonPressed: () => rejectWithReason(Reason.Collaborator), buttonText: "Collaborator", explanation: "Somebody else is required", image: Image.asset("assets/images/friends.png")),
            TaskRejectionReasonCard(onButtonPressed: () => rejectWithReason(Reason.TaskDependency), buttonText: "Task", explanation: "Another task must be completed", image: Image.asset("assets/images/list.png")),
            SizedBox(width: CustomTheme.standardHorizontalPadding.right * 0.7),
          ]),
        ),
        const SectionTitlePadded("Time"),
        SingleChildScrollView(
          physics: const BouncingScrollPhysics(),
          scrollDirection: Axis.horizontal,
          child: Row(children: [
            SizedBox(width: CustomTheme.standardHorizontalPadding.left * 0.7),
            TaskRejectionReasonCard(onButtonPressed: () => rejectWithReason(Reason.LackOfTime), buttonText: "Not enough", explanation: "There is not enough time right now", image: Image.asset("assets/images/hourglass.png")),
            TaskRejectionReasonCard(onButtonPressed: () => rejectWithReason(Reason.Schedule), buttonText: "Not now", explanation: "Right now is not the proper time", image: Image.asset("assets/images/schedule.png")),
            SizedBox(width: CustomTheme.standardHorizontalPadding.right * 0.7),
          ]),
        ),
        const SectionTitlePadded("Task Properties"),
        SingleChildScrollView(
          physics: const BouncingScrollPhysics(),
          scrollDirection: Axis.horizontal,
          child: Row(children: [
            SizedBox(width: CustomTheme.standardHorizontalPadding.left * 0.7),
            TaskRejectionReasonCard(onButtonPressed: () => rejectWithReason(Reason.Priority), buttonText: "Priority", explanation: "The task is not as high a priority", image: Image.asset("assets/images/bring.png")),
            TaskRejectionReasonCard(onButtonPressed: () => rejectWithReason(Reason.Delete), buttonText: "Delete", explanation: "This task is no longer required", image: Image.asset("assets/images/delete.png")),
            SizedBox(width: CustomTheme.standardHorizontalPadding.right * 0.7),
          ]),
        ),
        const SizedBox(
          height: CustomTheme.standardSeparation,
        ),
        Align(
          alignment: Alignment.center,
          child: TextButton(
            onPressed: () {},
            child: const Text("Other"),
          ),
        ),
        const SizedBox(
          height: CustomTheme.standardSeparation * 2,
        ),
      ],
    ),
  )

这是卡片的代码(发出阴影的东西):

class CardCustom extends StatelessWidget {
Widget? child;
EdgeInsetsGeometry? innerPadding;
EdgeInsetsGeometry? outerPadding;

CardCustom({Key? key, this.child, this.innerPadding, this.outerPadding}) : super(key: key);

@override
Widget build(BuildContext context) {
  return Padding(
    padding: outerPadding ?? EdgeInsets.fromLTRB(CustomTheme.standardHorizontalPadding.left, 0, CustomTheme.standardHorizontalPadding.right, CustomTheme.standardSeparation),
    child: Container(
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: CustomTheme.borderRadius,
        boxShadow: [BoxShadow(
          color: const Color(0xFF887AA6).withAlpha(25),
          spreadRadius: 0,
          blurRadius: 40,
          offset: const Offset(0, 4),
        )],
      ),
      child: Padding(
        padding: innerPadding ?? EdgeInsets.fromLTRB(CustomTheme.standardHorizontalPadding.left, CustomTheme.standardSeparation, CustomTheme.standardHorizontalPadding.right, CustomTheme.standardSeparation),
        child: child,
      ),
    ),
  );
}
}

发生这种情况是因为对于 2 个元素,SingleChildScrollView 被视为一行,因为不需要滚动。仅当将第 3 个元素添加到列表使其溢出时,该小部件才可滚动。

解决方法之一是在 SingleChildScrollView 的填充参数中添加 EdgeInsets.symmetric(vertical: value)。

另一种解决方法是删除 Outer Padding Widget 并在 CardCustom 的 Container 的边距参数中添加 EdgeInsets.symmetric(vertical: value)。

我最终使用 clipBehavior: Clip.none 从这个 post 解决了它:How to fix cropped shadow in a Horizontal List View in Flutter