I am creating a horizontal scroll with cards that cast a shadow.
I do not understand the reason why if I have 3 cards the shadow gets "clipped" but if I have 2 it doesn't.
This is how it looks when I have 3 or more elements (I suspect is more elements than those that fit in the screen).
How can I avoid this behaviour?
I have a Column inside a SingleChildScrollView. Inside that column, there are SingleChildScrollViews with Rows of cards.
This is the code inside the scaffold:
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,
),
],
),
)
And this is the code of the card (what emits the shadow):
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,
),
),
);
}
}
I ended up solving it using clipBehavior: Clip.none
from this post: How to fix cropped shadow in a Horizontal List View in Flutter