Xamarin - radial progress component issue

I am trying to implement the RadialProgress component ( https://components.xamarin.com/view/radialprogress ) in my application. I managed to get it on the screen and change the color of progress, but I can’t find a way to change the inner color of the circle.

The RadialProgressView object itself has a BackgroundTintMode field that accepts DuffPorter.Mode, but whenever I try to set the background color mode, the application breaks into this message (Message = "no method with name =" setBackgroundTintMode 'signature =' (Landroid / graphic / PorterDuff $ Mode;))

Is there a way to do what I want?

Thanks!

+5
source share
2 answers

Yes, it can be done. Although not very straightforward or even convenient.

First, let me plunge a bit into the RadialProgressView drawing RadialProgressView (as shown in the Xamarin Studio Assembly Browser):

  protected override void OnDraw(Canvas canvas) { // ... there 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); } 

We notice several colors here, for example bgCirclePaint and bgBorderPaint . If we can change the value of these variables, we can change the color with which the ProgressView will be colored.

The problem is that RadialProgressView does not expose fields - they are all private, so just inheriting from RadialProgressView will not allow us to set them to a new value.

However, we can use reflection to change these private fields, for example:

  var textPaintMember = typeof(RadialProgressView).GetField("textPaint", BindingFlags.Instance | BindingFlags.NonPublic); textPaintMember.SetValue(Instance, MyNewSuperCoolColorPaint); 

By combining the two, we can create a new custom class as follows:

 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); } } 

This will give us the result we will accomplish:

2

Note. It is probably wise to notice that we are making improper use of private fields: we manipulate them from outside the class in which they live. If Xamarin ever decides to change the way RadialProgressView , or even just renames one of the private variables, our code will not work at run time. The best way to approach this problem would probably be to simply ask Xamarin to provide the getters / setters you need. But hey it's so much cooler;)

+8
source

You can try to implement a custom ViewRenderer and access the main Android user views to change them the way you want. https://blog.xamarin.com/using-custom-controls-in-xamarin.forms-on-android/

The error associated with the setBackgroundTintMode method indicates that you may need to update the Xamarin platform to ensure that the latest APIs are available.

+1
source

All Articles