如何创建堆叠波浪容器
How to create stacked wave containers
我想用这个波浪和相同的曲线来实现这个屏幕,我试图将多个容器堆叠起来以获得这个形状,但我做不到,屏幕的顶部将是图像滑块
这是我用来绘制此屏幕的代码
Scaffold(
body: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
decoration: BoxDecoration(
gradient: LinearGradient(
end: Alignment.centerRight,
begin: Alignment.centerLeft,
colors: [
blueColor,
lightColor,
],
),
),
child: Stack(
alignment: Alignment.topCenter,
children: [
Container(
height: MediaQuery.of(context).size.height * .5,
decoration: BoxDecoration(),
child: Stack(
children: [
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height * .5,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(100),
),
image: DecorationImage(
image: AssetImage('assets/images/bg.png'),
fit: BoxFit.cover)),
),
Positioned(
bottom: 0,
child: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height * .08,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(150),
topLeft: Radius.circular(150),
),
gradient: LinearGradient(
end: Alignment.centerRight,
begin: Alignment.centerLeft,
colors: [
blueColor,
lightColor,
],
),
),
),
),
],
),
),
Positioned(
bottom: 0,
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
end: Alignment.centerRight,
begin: Alignment.centerLeft,
colors: [
blueColor,
lightColor,
],
),
),
child: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height * .5,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(120),
),
color: Colors.white),
),
),
),
],
),
),
);
但这是我有但不知道要完成的结果
所以有人可以帮助我吗!
你可以用 CustomPainter
来做这个,下面是你的做法和外观。
class StackedWaves extends StatelessWidget {
const StackedWaves({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return CustomPaint(
size: Size(MediaQuery.of(context).size.width,
MediaQuery.of(context).size.height),
painter: StackedWavesPainter(),
);
}
}
class StackedWavesPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..shader = LinearGradient(colors: [
Colors.green,
Colors.lightGreenAccent,
]).createShader(Offset.zero & size);
final double side = 80;
final double radius = 80;
final path = Path()
..moveTo(0, size.height / 2 + side)
..arcToPoint(Offset(side, size.height / 2),
radius: Radius.circular(radius))
..lineTo(size.width - side, size.height / 2)
..arcToPoint(Offset(size.width, size.height / 2 - side),
radius: Radius.circular(radius), clockwise: false)
..lineTo(size.width, size.height)
..lineTo(0, size.height)
..close();
canvas.save();
canvas.drawPath(path, paint);
canvas.restore();
canvas.save();
canvas.translate(0, 100);
canvas.drawPath(path, Paint()..color = Colors.white);
canvas.restore();
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}
当然,如果你愿意,你可以使用变量“side”和“radius”,只要确保它们的差异不超过 20 左右,我见过你是否像那样改变它可能得不到你想要的结果。
我想用这个波浪和相同的曲线来实现这个屏幕,我试图将多个容器堆叠起来以获得这个形状,但我做不到,屏幕的顶部将是图像滑块
这是我用来绘制此屏幕的代码
Scaffold(
body: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
decoration: BoxDecoration(
gradient: LinearGradient(
end: Alignment.centerRight,
begin: Alignment.centerLeft,
colors: [
blueColor,
lightColor,
],
),
),
child: Stack(
alignment: Alignment.topCenter,
children: [
Container(
height: MediaQuery.of(context).size.height * .5,
decoration: BoxDecoration(),
child: Stack(
children: [
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height * .5,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(100),
),
image: DecorationImage(
image: AssetImage('assets/images/bg.png'),
fit: BoxFit.cover)),
),
Positioned(
bottom: 0,
child: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height * .08,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(150),
topLeft: Radius.circular(150),
),
gradient: LinearGradient(
end: Alignment.centerRight,
begin: Alignment.centerLeft,
colors: [
blueColor,
lightColor,
],
),
),
),
),
],
),
),
Positioned(
bottom: 0,
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
end: Alignment.centerRight,
begin: Alignment.centerLeft,
colors: [
blueColor,
lightColor,
],
),
),
child: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height * .5,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(120),
),
color: Colors.white),
),
),
),
],
),
),
);
但这是我有但不知道要完成的结果
所以有人可以帮助我吗!
你可以用 CustomPainter
来做这个,下面是你的做法和外观。
class StackedWaves extends StatelessWidget {
const StackedWaves({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return CustomPaint(
size: Size(MediaQuery.of(context).size.width,
MediaQuery.of(context).size.height),
painter: StackedWavesPainter(),
);
}
}
class StackedWavesPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..shader = LinearGradient(colors: [
Colors.green,
Colors.lightGreenAccent,
]).createShader(Offset.zero & size);
final double side = 80;
final double radius = 80;
final path = Path()
..moveTo(0, size.height / 2 + side)
..arcToPoint(Offset(side, size.height / 2),
radius: Radius.circular(radius))
..lineTo(size.width - side, size.height / 2)
..arcToPoint(Offset(size.width, size.height / 2 - side),
radius: Radius.circular(radius), clockwise: false)
..lineTo(size.width, size.height)
..lineTo(0, size.height)
..close();
canvas.save();
canvas.drawPath(path, paint);
canvas.restore();
canvas.save();
canvas.translate(0, 100);
canvas.drawPath(path, Paint()..color = Colors.white);
canvas.restore();
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}
当然,如果你愿意,你可以使用变量“side”和“radius”,只要确保它们的差异不超过 20 左右,我见过你是否像那样改变它可能得不到你想要的结果。