如何實現(xiàn)一個雙向PK進(jìn)度條
在Flutter應(yīng)用中,進(jìn)度條是一個非常常見的組件。而雙向PK進(jìn)度條則能夠展示兩個對立的數(shù)值,如對戰(zhàn)中的雙方得分對比等。本文將介紹如何實現(xiàn)一個具有雙向PK效果的進(jìn)度條航棱,并支持豎直和斜角兩種過渡效果。
1. 需求
我們需要一個自定義的雙向PK進(jìn)度條萌衬,要求如下:
- 能夠顯示兩個對立的數(shù)值饮醇。
- 進(jìn)度條兩端有圓角。
- 中間過渡部分可以是豎直或者45度斜角秕豫。
- 支持自定義顏色和高度朴艰。
2. 效果
通過我們的實現(xiàn),可以得到如下效果:
3. 實現(xiàn)思路
- 定義組件:創(chuàng)建一個自定義的PKProgressBar組件混移,包含左右兩側(cè)的數(shù)值祠墅、顏色、高度和過渡類型歌径。
-
繪制左側(cè)和右側(cè)的圓角矩形:使用
CustomPainter
來繪制左右兩部分的圓角矩形毁嗦。 - 處理中間過渡部分:根據(jù)過渡類型繪制豎直或者45度斜角的過渡效果。
4. 實現(xiàn)代碼
下面是實現(xiàn)雙向PK進(jìn)度條的完整代碼:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('雙向PK進(jìn)度條')),
body: const Center(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 16),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
PKProgressBar(
leftValue: 75,
rightValue: 150,
leftColor: Colors.blue,
rightColor: Colors.red,
height: 20,
transitionType: TransitionType.diagonal, // 設(shè)置過渡類型為斜角
),
SizedBox(height: 50),
PKProgressBar(
leftValue: 90,
rightValue: 55,
leftColor: Colors.brown,
rightColor: Colors.green,
height: 20,
transitionType: TransitionType.vertical, // 設(shè)置過渡類型為豎直
),
],
),
)),
),
);
}
}
// 定義過渡類型枚舉
enum TransitionType { vertical, diagonal }
class PKProgressBar extends StatelessWidget {
final double leftValue;
final double rightValue;
final Color leftColor;
final Color rightColor;
final double height;
final TransitionType transitionType;
const PKProgressBar({
super.key,
required this.leftValue,
required this.rightValue,
required this.leftColor,
required this.rightColor,
this.height = 20.0,
this.transitionType = TransitionType.diagonal, // 默認(rèn)過渡類型為斜角
});
@override
Widget build(BuildContext context) {
return CustomPaint(
size: Size(double.infinity, height),
painter: PKProgressPainter(
leftValue: leftValue,
rightValue: rightValue,
leftColor: leftColor,
rightColor: rightColor,
transitionType: transitionType,
),
);
}
}
class PKProgressPainter extends CustomPainter {
final double leftValue;
final double rightValue;
final Color leftColor;
final Color rightColor;
final TransitionType transitionType;
PKProgressPainter({
required this.leftValue,
required this.rightValue,
required this.leftColor,
required this.rightColor,
required this.transitionType,
});
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()..style = PaintingStyle.fill;
final double totalValue = leftValue + rightValue;
final double leftWidth = (leftValue / totalValue) * size.width;
final double rightWidth = (rightValue / totalValue) * size.width;
final double radius = size.height / 2;
// 左側(cè)帶圓角的矩形
final leftRRect = RRect.fromLTRBAndCorners(
0,
0,
leftWidth,
size.height,
topLeft: Radius.circular(radius),
bottomLeft: Radius.circular(radius),
);
// 右側(cè)帶圓角的矩形
final rightRRect = RRect.fromLTRBAndCorners(
leftWidth,
0,
size.width,
size.height,
topRight: Radius.circular(radius),
bottomRight: Radius.circular(radius),
);
// 繪制左側(cè)部分
paint.color = leftColor;
canvas.drawRRect(leftRRect, paint);
// 繪制右側(cè)部分
paint.color = rightColor;
canvas.drawRRect(rightRRect, paint);
// 根據(jù)過渡類型繪制中間部分
if (transitionType == TransitionType.vertical) {
// 豎直過渡
final middleRect = Rect.fromLTWH(
leftWidth - radius,
0,
2 * radius,
size.height,
);
paint.color = rightColor;
canvas.drawRect(middleRect, paint);
} else if (transitionType == TransitionType.diagonal) {
// 斜角過渡回铛,形成45度斜線
final leftPath = Path()
..moveTo(leftWidth - size.height / 2, 0)
..lineTo(leftWidth + size.height / 2, size.height)
..lineTo(leftWidth - size.height / 2, size.height)
..close();
paint.color = leftColor;
canvas.drawPath(leftPath, paint);
// 斜角過渡狗准,形成45度斜線
final rightPath = Path()
..moveTo(leftWidth - size.height / 2, 0)
..lineTo(leftWidth, 0)
..lineTo(leftWidth, size.height)
..close();
paint.color = rightColor;
canvas.drawPath(rightPath, paint);
}
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return false;
}
}
在這個實現(xiàn)中芯急,我們通過CustomPainter
來自定義繪制PK進(jìn)度條,并根據(jù)過渡類型繪制豎直或斜角的過渡效果驶俊。通過這些代碼,你可以輕松實現(xiàn)一個具有雙向PK效果的進(jìn)度條免姿,并根據(jù)需求調(diào)整樣式和效果饼酿。