我在 Figma 中有以下设计,我想在 Flutter 中实现。该设计是一个锯齿形图案,代表一个进度指示器,它向终点移动。步骤完成后,其上会出现一个自定义复选标记,将其标记为已完成。这是设计:
我尝试在 Flutter 中使用
Paint
类,但它没有给我想要的结果。
我并没有真正投入太多工作,它还远未完美,但我希望这会有所帮助。警告,这段代码还不是“干净”和“高效”:
import 'package:flutter/material.dart';
void main() {
runApp(
const MyApp(),
);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: "Wavy UI",
debugShowCheckedModeBanner: false,
home: WavyUI(),
);
}
}
class WavyUI extends StatelessWidget {
const WavyUI({super.key});
@override
Widget build(BuildContext context) {
final double rangePerItem = 90;
return Padding(
padding: const EdgeInsets.all(8.0),
child: Stack(
children: [
Container(
margin: EdgeInsets.only(top: rangePerItem * 0),
child: WavyItem(
text: "Wavy 01",
wavyDirection: AxisDirection.right,
),
),
Container(
margin: EdgeInsets.only(top: rangePerItem * 1),
child: WavyItem(
text: "Wavy 02",
wavyDirection: AxisDirection.left,
),
),
Container(
margin: EdgeInsets.only(top: rangePerItem * 2),
child: WavyItem(
text: "Wavy 03",
wavyDirection: AxisDirection.right,
),
),
Container(
margin: EdgeInsets.only(top: rangePerItem * 3),
child: WavyItem(
text: "Wavy 04",
wavyDirection: AxisDirection.left,
),
),
],
),
);
}
}
class WavyItem extends StatelessWidget {
const WavyItem({
super.key,
required this.text,
required this.wavyDirection,
});
final String text;
final AxisDirection wavyDirection;
BorderRadius _getBorderRadius(double circularRadius) {
if (wavyDirection == AxisDirection.left) {
return BorderRadius.only(
topLeft: Radius.circular(circularRadius),
bottomLeft: Radius.circular(circularRadius),
);
//
} else {
return BorderRadius.only(
topRight: Radius.circular(circularRadius),
bottomRight: Radius.circular(circularRadius),
);
}
}
@override
Widget build(BuildContext context) {
final Widget textWidget = Container(
width: 100,
height: 100,
alignment: Alignment.center,
child: Text(
text,
style: const TextStyle(fontSize: 15),
),
);
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
(wavyDirection == AxisDirection.right) ? textWidget : const SizedBox.shrink(),
Container(
width: 100,
height: 100,
alignment: Alignment.center,
decoration: BoxDecoration(
color: const Color.fromARGB(255, 110, 150, 220),
borderRadius: _getBorderRadius(60),
),
child: Container(
width: 100,
height: 80,
margin: EdgeInsets.only(
right: (wavyDirection == AxisDirection.right) ? 10 : 0,
left: (wavyDirection == AxisDirection.right) ? 0 : 10,
),
decoration: BoxDecoration(
color: Colors.black,
borderRadius: _getBorderRadius(60),
),
child: const Icon(Icons.balance_outlined, color: Colors.white),
),
),
(wavyDirection == AxisDirection.left) ? textWidget : const SizedBox.shrink(),
],
);
}
}
稍微调整一下,您就会实现所需的 UI。干杯。
我尝试过锯齿形设计并进行逻辑检查是否满足您的要求
Container(
color: Colors.white,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Container(
width: 100,
height: 80,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(50),
bottomLeft: Radius.circular(50)),
color: Colors.white),
),
Container(
width: 100,
height: 80,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topRight: Radius.circular(50),
bottomRight: Radius.circular(50)),
color: Colors.orange),
),
],
),
Transform.translate(
offset: Offset(0, -10),
child: Container(
margin: EdgeInsets.only(left: 30),
width: 120,
height: 10,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topRight: Radius.circular(0),
bottomRight: Radius.circular(0)),
color: Colors.orange),
),
),
Transform.translate(
offset: Offset(0, -20),
child: Row(
children: [
Stack(alignment: Alignment.centerRight, children: [
Container(
width: 100,
height: 80,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(50),
bottomLeft: Radius.circular(50)),
color: Colors.orange),
),
Container(
width: 90,
height: 60,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(50),
bottomLeft: Radius.circular(50)),
color: Colors.blue),
),
]),
],
),
),
Row(
children: [
Container(
width: 100,
height: 80,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(50),
bottomLeft: Radius.circular(50)),
color: Colors.white),
),
Transform.translate(
offset: Offset(0, -30),
child: Container(
width: 100,
height: 80,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topRight: Radius.circular(50),
bottomRight: Radius.circular(50)),
color: Colors.orange),
),
),
],
),
Transform.translate(
offset: Offset(0, -40),
child: Row(
children: [
Stack(alignment: Alignment.centerRight, children: [
Container(
width: 100,
height: 80,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(50),
bottomLeft: Radius.circular(50)),
color: Colors.orange),
),
Container(
width: 90,
height: 60,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(50),
bottomLeft: Radius.circular(50)),
color: Colors.blue),
),
]),
],
),
),
Row(
children: [
Container(
width: 100,
height: 80,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(50),
bottomLeft: Radius.circular(50)),
color: Colors.white),
),
Transform.translate(
offset: Offset(0, -50),
child: Container(
width: 100,
height: 80,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topRight: Radius.circular(50),
bottomRight: Radius.circular(50)),
color: Colors.orange),
),
),
],
),
Transform.translate(
offset: Offset(0, -60),
child: Row(
children: [
Stack(alignment: Alignment.centerRight, children: [
Container(
width: 100,
height: 80,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(50),
bottomLeft: Radius.circular(50)),
color: Colors.orange),
),
Container(
width: 90,
height: 60,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(50),
bottomLeft: Radius.circular(50)),
color: Colors.blue),
),
]),
],
),
),
],
),
)