Hello,
I'm trying to draw a clock in Xamarin Android where the dial turns and the pointer not, it always points up. On the dial, moments must be drawn.
This is the design i'm working towards
I want to draw Moment objects on my clock (like the design shows).
public class Moment { public DateTime StartTime; public DateTime EndTime; public bool Successful; }
This is my custom view for the clock (basically drawing some circles).
public class ClockView : View { private float fullClockRadius { get { return ClockController.Instance.CalculateTotalClockRadius(this.Width, this.Height, paint.StrokeWidth); } } private float centerClockPartRadius { get { return ClockController.Instance.CalculateCenterClockPartRadius(this.Width, this.Height, paint.StrokeWidth); } } private Paint paint; public ClockView(Context context, IAttributeSet attrs) : base(context, attrs) { Initialize(); } public ClockView(Context context, IAttributeSet attrs, int defStyle) : base(context, attrs, defStyle) { Initialize(); } private void Initialize() { paint = new Paint(); } protected override void OnDraw(Canvas canvas) { // Set Paint for full clock drawing paint.Color = Color.White; paint.AntiAlias = true; paint.SetStyle(Paint.Style.Stroke); paint.StrokeWidth = (float)5.0; //Draw outer circle. canvas.DrawCircle(Width / 2, Height / 2, fullClockRadius, paint); //Change paint for centre clock part drawing. paint.SetStyle(Paint.Style.Fill); //Draw inner circle. canvas.DrawCircle(Width / 2, Height / 2, centerClockPartRadius, paint); //Change paint for triangle of digital time. paint.Color = Color.Orange; paint.SetStyle(Paint.Style.Fill); // Draw triangle. Path path = new Path(); // Move to left bottom of triangle that's about to be drawn. path.MoveTo((float)Width /2 - 25, (float)Height / 2 - (centerClockPartRadius - 50)); // Left bottom to right bottom triangle. path.LineTo((float)Width / 2 + 25, (float)Height / 2 - (centerClockPartRadius - 50)); // Left bottom to top of triangle. path.LineTo((float)Width / 2, (float)Height / 2 - centerClockPartRadius); // Closing draws the right bottom to top line. path.Close(); canvas.DrawPath(path, paint); } }
I had two ideas for solving this problem:
Another idea was to draw the moments like pieces of a pie chart are being drawn, but I couldn't get it working (the circle math was too hard on me).
If such a solution could be offered, that would be great.
How can I draw the Moment objects (with corresponding icons and click events) in my clock and redraw every x seconds?
Answers
Take a look at the
ArcLayout
library. It allows you to layout subviews in a circle (or any arc). I have a bindings library on Github here: https://github.com/SuavePirate/ArcLayoutYou could then just layout instances of
ImageView
in yourArcLayout
!Hey Alex,
im currently trying your solution.
However, with the Xaml it works fine, but I can't set properties like app:arc_angle="160" programmatically (runtime).
This question has also been asked on GitHub, but it got no response
Do you know how to do this?
Thanks in advance!
You're right! Good find. I haven't actually used this outside of a non-moving layout, so just setting the values in the layout file was all I really needed.
Here's another general approach I would consider:
Create an
AbsoluteLayout
, and set it's background to aDrawable
that is your circle (whether it is an image or xml). Then create yourImageViews
(orButtons
) for each of the individual pieces in the circle. Position those using theirlayout_margins
to get them in the spots you want. Then you can animate their x and y positions programmatically or just change theirLayoutParams
to move them at runtime.