我正在用 Flutter 做一个文件夹状的容器组件。
我正在使用下面的代码创建一个文件夹形状的容器并给它一个阴影效果。 (我从 Stack Overflow 得到了一些帮助。)
我想像上图一样给出自然的阴影效果。我做的阴影效果好难看
下面给大家展示一下我制作的阴影效果。我希望它像下面文本字段的阴影效果一样自然。
我试过各种方法,都做不出像上图那样自然的阴影。我太缺了
帮助我。
Column(
children: [
SizedBox(
height: 50,
),
ClipPath(
clipper: FolderShapeClipper(),
child: Card(
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(2)),
child: Container(
width: 274,
height: 188,
decoration: FolderShapeDecoration(
shadowColor: Color.fromRGBO(0, 0, 0, 0.2),
shadowBlurRadius: 5,
shadowOffset: Offset(-2, -2),
),
child: Column(
mainAxisAlignment:
MainAxisAlignment.spaceAround,
children: [
const SizedBox(
height: 12,
),
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 24),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: const [
Text('test'),
Icon(Icons.star),
],
),
),
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 24),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: const [
Text('count'),
Text('10'),
],
),
),
],
),
),
),
),
],
),
class FolderShapeClipper extends CustomClipper<Path> {
final a = 0.10;
final b = 0.25;
final c = 0.5;
@override
Path getClip(Size size) {
return Path()
..moveTo(size.width * a, 0)
..lineTo(0, size.height * b)
..lineTo(0, size.height)
..lineTo(size.width, size.height)
..lineTo(size.width, size.height * b)
..lineTo(size.width * c, size.height * b)
..lineTo(size.width * c, 0)
..lineTo(size.width * a, 0)
..close();
}
@override
bool shouldReclip(covariant CustomClipper<Path> oldClipper) {
return true;
}
}
class FolderShapeDecoration extends BoxDecoration {
final Color shadowColor;
final double shadowBlurRadius;
final Offset shadowOffset;
FolderShapeDecoration({
required this.shadowColor,
required this.shadowBlurRadius,
required this.shadowOffset,
});
@override
BoxPainter createBoxPainter([VoidCallback? onChanged]) {
return _FolderShapeBoxPainter(
shadowColor: shadowColor,
shadowBlurRadius: shadowBlurRadius,
shadowOffset: shadowOffset);
}
}
class _FolderShapeBoxPainter extends BoxPainter {
final Color shadowColor;
final double shadowBlurRadius;
final Offset shadowOffset;
final FolderShapeClipper clipper = FolderShapeClipper();
_FolderShapeBoxPainter({
required this.shadowColor,
required this.shadowBlurRadius,
required this.shadowOffset,
});
@override
void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {
final size = configuration.size!;
final borderPath = clipper.getClip(size);
final shadowPaint = Paint()
..color = shadowColor
..maskFilter = MaskFilter.blur(BlurStyle.outer, shadowBlurRadius);
canvas.drawPath(borderPath.shift(offset + shadowOffset), shadowPaint);
}
}
您还可以使用 Material 小部件,它具有提升 Container 或 SizedBox 等的 elevation 属性......并且看起来它有一个阴影。但是如果你想使用阴影属性,你应该改变偏移和模糊半径值。但我真的不知道哪些值最像自然阴影。
您可以使用 PhysicalModel 小部件 https://api.flutter.dev/flutter/widgets/PhysicalModel-class.html 或 DecoratedBox,然后在 BoxDecoration 中添加阴影列表。