我一直在尝试在我的应用程序上实现RadialProgress组件(https://components.xamarin.com/view/radialprogress).我设法在屏幕上显示它,并更改进度颜色,但我找不到改变圆圈内部颜色的方法.
RadialProgressView对象本身有一个BackgroundTintMode字段,它接受DuffPorter.Mode,但每当我尝试设置背景色调模式时,应用程序就会破坏此消息(Message ="no method with name ='setBackgroundTintMode'train ='(Landroid/graphics/PorterDuff $模式;))
有没有办法做我想要的?
谢谢!
是的,可以做到.虽然不是以非常直截了当的方式甚至是可维护的方式.
首先,让我们深入了解一下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);
}
Run Code Online (Sandbox Code Playgroud)
我们在这里注意到一些颜色,比如bgCirclePaint和bgBorderPaint.如果我们能够更改这些变量的值,我们将能够更改绘制ProgressView的颜色.
问题是RadialProgressView不暴露字段 - 它们都是私有的,因此简单地继承RadialProgressView将不允许我们将它们设置为新值.
但是,我们可以利用反射来更改这些私有字段,如下所示:
var textPaintMember = typeof(RadialProgressView).GetField("textPaint", BindingFlags.Instance | BindingFlags.NonPublic);
textPaintMember.SetValue(Instance, MyNewSuperCoolColorPaint);
Run Code Online (Sandbox Code Playgroud)
通过将两者结合起来,我们可以提出一个新的,可自定义的类,如下所示:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
这将使我们获得我们追求的结果:
注意:注意到我们正在不正当地使用私有字段可能是明智的:我们正在从他们所在的类之外操纵它们.如果Xamarin决定改变RadialProgressView实现的方式,或者甚至只重命名其中一个私有变量,我们的代码将在运行时失败.解决这个问题的更好方法可能是让Xamarin提供你需要的getter/setter.但是,嘿,这种方式更凉爽;)
| 归档时间: |
|
| 查看次数: |
945 次 |
| 最近记录: |