我一直在尝试在我的应用上实现RadialProgress组件(https://components.xamarin.com/view/radialprogress)。 我设法在屏幕上显示它,并改变进度颜色,但我找不到改变圆圈内部颜色的方法。
RadialProgressView对象本身有一个BackgroundTintMode字段,它接受DuffPorter.Mode,但每当我尝试设置背景色调模式时,应用程序就会中断此消息(Message =" no name with name =' setBackgroundTintMode& #39;签名='(Landroid / graphics / PorterDuff $ Mode;))
有没有办法做我想做的事?
谢谢!
答案 0 :(得分:8)
是的,可以做到。虽然不是以非常直截了当的方式甚至是可维护的方式。
首先,让我们深入了解RadialProgressView
的绘图代码(由Xamarin Studio Assembly Browser公开):
protected override void OnDraw(Canvas canvas)
{
// ... there's more stuff here, but you get the idea
canvas.DrawCircle(this.bgCx, this.bgCy, this.radius, this.bgCirclePaint);
canvas.DrawCircle(this.bgCx, this.bgCy, this.innerLineRadius, this.bgBorderPaint);
canvas.DrawText(this.valueText, this.textX, this.textY, this.textPaint);
}
我们注意到了一些颜色,例如bgCirclePaint
和bgBorderPaint
。如果我们能够更改这些变量的值,我们将能够更改绘制ProgressView的颜色。
问题是RadialProgressView
没有公开字段 - 它们都是私有的,因此只需继承RadialProgressView
就不允许我们将它们设置为新值。
但是,我们可以使用reflection更改这些私有字段,如下所示:
var textPaintMember = typeof(RadialProgressView).GetField("textPaint", BindingFlags.Instance | BindingFlags.NonPublic);
textPaintMember.SetValue(Instance, MyNewSuperCoolColorPaint);
通过将两者结合起来,我们可以提出一个新的可自定义的类:
public class CustomizableRadialProgressView : RadialProgressView
{
public CustomizableRadialProgressView(Context context) : base(context)
{
}
public void SetTextColor(Color color)
{
var paint = new Paint();
paint.SetTypeface(Typeface.DefaultBold);
paint.Color = color;
paint.AntiAlias = true;
var textPaintMember = typeof(RadialProgressView).GetField("textPaint", BindingFlags.Instance | BindingFlags.NonPublic);
textPaintMember.SetValue(this, paint);
}
public void SetCircleColor(Color color)
{
var paint = new Paint();
paint.SetStyle(Paint.Style.Fill);
paint.Color = color;
paint.AntiAlias = true;
var circlePaintMember = typeof(RadialProgressView).GetField("bgCirclePaint", BindingFlags.Instance | BindingFlags.NonPublic);
circlePaintMember.SetValue(this, paint);
}
public void SetBorderColor(Color color)
{
var paint = new Paint();
paint.SetStyle(Paint.Style.Stroke);
paint.Color = color;
paint.AntiAlias = true;
var circlePaintMember = typeof(RadialProgressView).GetField("bgBorderPaint", BindingFlags.Instance | BindingFlags.NonPublic);
circlePaintMember.SetValue(this, paint);
}
public void SetProgressPackgroundColor(Color color)
{
var paint = new Paint();
paint.SetStyle(Paint.Style.Stroke);
paint.Color = color;
paint.AntiAlias = true;
var circlePaintMember = typeof(RadialProgressView).GetField("bgProgressPaint", BindingFlags.Instance | BindingFlags.NonPublic);
circlePaintMember.SetValue(this, paint);
}
}
这将为我们带来我们之后的结果:
注意:可能明智的做法是注意到我们正在不正当地使用私人领域:我们正在从他们所在的班级之外操纵他们。如果Xamarin决定改变方式RadialProgressView
实现,甚至只重命名其中一个私有变量,我们的代码将在运行时失败。解决这个问题的更好方法可能是让Xamarin提供你需要的getter / setter。但是,嘿,通过这种方式它会变得更酷;)
答案 1 :(得分:1)
您可以尝试实施自定义ViewRenderer并访问基础本机Android视图,以根据需要进行修改。 https://blog.xamarin.com/using-custom-controls-in-xamarin.forms-on-android/
关于" setBackgroundTintMode"的错误方法表示您可能需要更新Xamarin平台以确保最新的API可用