我正在尝试设计一个显示进程当前状态的控件,如下图所示。
因此,我们有一个圆形显示状态,其中包含里程碑或检查点的彩色部分。在图像中,我们已经完成了前两个阶段,第三阶段已经完成了70%。
我知道Jquery中有一个非常相似的控件。但我不确定,如果我可以使用Xamarin Forms中的第三方控件。如果没有第三方控制,我应该如何进行设计。
我应该只为不同阶段创建图像并显示图像吗?或者我应该创建一个可以采用两个值的自定义控件,"里程碑"和" percentage_complete",然后可以设计一个饼图?
答案 0 :(得分:4)
使用NGraphics
w / NControl
,您可以创建“完整度计”的“矢量”版本,而无需创建平台渲染器或需要将Skia
等库添加到项目中。< / p>
注意:SkiaSharp和其他原生的2d / 3d库很棒,但是为应用程序增加了很多开销,如果你不需要它们的所有功能,那么膨胀(应用程序大小,内存使用,初始化时间等等)。 。)不值得(恕我直言)。
re:https://github.com/praeclarum/NGraphics
我剥离了MultiSegmentProgressControl
,我向你展示了弧形绘制的基础知识。我所做的完整版本允许您添加和动画多个细分,显示百分比,触摸时突破细分等...
使用NControl
您可以使用触摸元素创建复合控件,因此您需要在多大程度上接受它。
re:https://github.com/chrfalch/NControl
public class MultiSegmentProgressControl2 : NControlView
{
double ringWidth = 50;
double ringInnerWidth = 100;
SolidBrush redBush = new SolidBrush(Colors.Red);
RadialGradientBrush redSegmentBrush = new RadialGradientBrush(
new Point(0.5, 0.5),
new Size(.75, .75),
Colors.LightGray,
Colors.Red);
SolidBrush blueBush = new SolidBrush(Colors.Blue);
RadialGradientBrush blueSegmentBrush = new RadialGradientBrush(
new Point(0.5, 0.5),
new Size(.75, .75),
Colors.LightGray,
Colors.Green);
Tuple<double, double> _redSegment;
public Tuple<double, double> RedSegment { get { return _redSegment; } set { _redSegment = value; Invalidate(); } }
Tuple<double, double> _greenSegment;
public Tuple<double, double> GreenSegment { get { return _greenSegment; } set { _greenSegment = value; Invalidate(); } }
public override void Draw(ICanvas canvas, Rect rect)
{
canvas.FillEllipse(rect.TopLeft, rect.Size, Colors.Gray);
var n = rect;
n.X += ringWidth;
n.Y = n.X;
n.Width -= ringWidth * 2;
n.Height = n.Width;
var i = n;
canvas.FillEllipse(n.TopLeft, n.Size, Colors.LightGray);
n.X += ringInnerWidth;
n.Y = n.X;
n.Width -= ringInnerWidth * 2;
n.Height = n.Width;
canvas.FillEllipse(n.TopLeft, n.Size, Colors.White);
var r = rect.Width / 2;
DrawSegment(canvas, rect, ringWidth, redBush, r, _redSegment.Item1, _redSegment.Item2);
DrawSegment(canvas, i, ringInnerWidth, redSegmentBrush, r - ringWidth, _redSegment.Item1, _redSegment.Item2);
DrawSegment(canvas, rect, ringWidth, blueBush, r, _greenSegment.Item1, _greenSegment.Item2);
DrawSegment(canvas, i, ringInnerWidth, blueSegmentBrush, r - ringWidth, _greenSegment.Item1, _greenSegment.Item2);
}
void DrawSegment(ICanvas canvas, Rect rect, double width, Brush brush, double r, double s, double f)
{
canvas.DrawPath(new PathOp[]{
new MoveTo(SegmentEdgePoint(rect.Center, r, s)),
new ArcTo(new Size(rect.Height / 2, rect.Width / 2), false, true, SegmentEdgePoint(rect.Center, r, f)),
new LineTo(SegmentEdgePoint(rect.Center, r - width, f)),
new ArcTo(new Size(r, r), false, false, SegmentEdgePoint(rect.Center, r - width, s)),
new LineTo(SegmentEdgePoint(rect.Center, r, s)),
new ClosePath()
}, null, brush);
}
Point SegmentEdgePoint(Point c, double r, double d)
{
return new Point(
c.X + r * Math.Cos(d * Math.PI / 180),
c.Y + r * Math.Sin(d * Math.PI / 180)
);
}
}
使用NGraphics
时,我强烈建议您使用NGraphics.Editor
或Xamarin'Workbook来交互式设计控件:
答案 1 :(得分:3)
如果找不到已经完成的解决方案(强烈推荐,如果你能找到一个解决方案!)那么创建一个带有DrawSegment调用的图形库增量调用的控件可能会有效。