[英]How to draw a custom rounded rectangle border (ShapeBorder), in Flutter?
[英]How to draw a rounded border pie chart
使用CustomPaint小部件可以輕松實現與您的圖表非常相似的版本。
要實現這一點,您只需要一個非常基本的CustomPainter即可在其 canvas 上繪制弧線。 圓角效果是通過用於繪制筆畫的Paint的strokeCap屬性實現的。 遺憾的是StrokeCap僅支持圓形和方形筆划結尾。
無法通過此實現像屏幕截圖中的圓角矩形效果。
Colors 是通過為每個筆划使用單獨的Paint來實現的。
// this is used to pass data about chart values to the widget
class PieChartData {
const PieChartData(this.color, this.percent);
final Color color;
final double percent;
}
// our pie chart widget
class PieChart extends StatelessWidget {
PieChart({
required this.data,
required this.radius,
this.strokeWidth = 8,
this.child,
Key? key,
}) : // make sure sum of data is never ovr 100 percent
assert(data.fold<double>(0, (sum, data) => sum + data.percent) <= 100),
super(key: key);
final List<PieChartData> data;
// radius of chart
final double radius;
// width of stroke
final double strokeWidth;
// optional child; can be used for text for example
final Widget? child;
@override
Widget build(context) {
return CustomPaint(
painter: _Painter(strokeWidth, data),
size: Size.square(radius),
child: SizedBox.square(
// calc diameter
dimension: radius * 2,
child: Center(
child: child,
),
),
);
}
}
// responsible for painting our chart
class _PainterData {
const _PainterData(this.paint, this.radians);
final Paint paint;
final double radians;
}
class _Painter extends CustomPainter {
_Painter(double strokeWidth, List<PieChartData> data) {
// convert chart data to painter data
dataList = data
.map((e) => _PainterData(
Paint()
..color = e.color
..style = PaintingStyle.stroke
..strokeWidth = strokeWidth
..strokeCap = StrokeCap.round,
// remove padding from stroke
(e.percent - _padding) * _percentInRadians,
))
.toList();
}
static const _percentInRadians = 0.062831853071796;
// this is the gap between strokes in percent
static const _padding = 4;
static const _paddingInRadians = _percentInRadians * _padding;
// 0 radians is to the right, but since we want to start from the top
// we'll use -90 degrees in radians
static const _startAngle = -1.570796 + _paddingInRadians / 2;
late final List<_PainterData> dataList;
@override
void paint(Canvas canvas, Size size) {
final rect = Offset.zero & size;
// keep track of start angle for next stroke
double startAngle = _startAngle;
for (final data in dataList) {
final path = Path()..addArc(rect, startAngle, data.radians);
startAngle += data.radians + _paddingInRadians;
canvas.drawPath(path, data.paint);
}
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return oldDelegate != this;
}
}
您可以查看dartpad來試驗一個工作示例。
我很肯定您在該圖片中提供的相同圖表可以使用 CustomPainter 實現,但這會復雜得多。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.