Xamarin Android - how to draw icons inside a circle

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.

Context

This is the design i'm working towards

This is my progress

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

Efforts

I had two ideas for solving this problem:

  1. Draw a moment, turn clock a certain amount of degrees, draw a moment, etc.
  2. Draw moments on wished location.

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.

My question

How can I draw the Moment objects (with corresponding icons and click events) in my clock and redraw every x seconds?

Answers

  • AlexDunnAlexDunn USMember ✭✭✭

    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/ArcLayout

    You could then just layout instances of ImageView in your ArcLayout!

  • jacobuspjacobusp NLMember

    @AlexDunn said:
    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/ArcLayout

    You could then just layout instances of ImageView in your ArcLayout!

    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!

  • AlexDunnAlexDunn USMember ✭✭✭

    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 a Drawable that is your circle (whether it is an image or xml). Then create your ImageViews (or Buttons) for each of the individual pieces in the circle. Position those using their layout_margins to get them in the spots you want. Then you can animate their x and y positions programmatically or just change their LayoutParams to move them at runtime.

Sign In or Register to comment.