How to draw a polyline / polygon on existing view

ArnoldBoschArnoldBosch ZAMember ✭✭
edited May 2013 in Xamarin.Android

Hi There

I need some help to draw a polygon or polyline on an existing view struggling for 2days now

XML

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <Button
        android:id="@+id/MyButton"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/Hello" />
    <View
        android:layout_width="match_parent"
        android:layout_height="400dp"
        android:background="@android:color/black"
        android:id="@+id/canvas1" />
</LinearLayout>

this is code I found that works

         button.Click += delegate {
                        SetContentView(new FilledPolygon(this));
                    }; 

the method

public class FilledPolygon : View
    {
        View vw;
        private readonly PointF[] _points = new[]
                                            {
                                                new PointF(0, 0),
                                                new PointF(200, 200),
                                                new PointF(200, 500),
                                                new PointF(600, 600),
                                                new PointF(400, 200),
                                                new PointF(0, 0)
                                            };
        public FilledPolygon(Context context)
            : base(context)
        {
        }
        protected override void OnDraw(Canvas canvas)
        {
            base.OnDraw(canvas);
            var path = new Path();
            path.MoveTo(_points[0].X, _points[0].Y);
            for (var i = 1; i < _points.Length; i++)
            {
                path.LineTo(_points[i].X, _points[i].Y);
            }
            var paint = new Paint
            {
                Color = Color.Black
            };
            // We can use Paint.Style.Stroke if we want to draw a "hollow" polygon,
            // But then we had better set the .StrokeWidth property on the paint.
            paint.SetStyle(Paint.Style.Stroke);
            paint.StrokeWidth = 3f;
            canvas.DrawPath(path, paint);

        }
    }
}

I would just like to draw those lines on the view I created

any help would be deeply appreciated :)

Kind Regards

Posts

  • DWestyDWesty USMember ✭✭

    If you notice in the code that works you are setting the content view to NEW view not writing over an existing view.

    Normally if you want special behavior for a view; especially how it is drawn you need to subclass/extend what ever base View you want and override the OnDraw behavior to do what you want. Just like the example you posted.

  • CheesebaronCheesebaron DKInsider, University mod

    You XML contains:

    <View
        android:layout_width="match_parent"
        android:layout_height="400dp"
        android:background="@android:color/black"
        android:id="@+id/canvas1" />
    

    If you look carefully you are referencing View and not your own FilledPolygon. So instead use:

    <my.awesome.namespace.FilledPolygon
        android:layout_width="match_parent"
        android:layout_height="400dp"
        android:background="@android:color/black"
        android:id="@+id/canvas1" />
    

    Also notice you are setting the background to black, but that is also the color of your Paint.

  • ArnoldBoschArnoldBosch ZAMember ✭✭

    Hi

    Thank you for the replies I've sorted out my problem rather made it populate the polygon in a new activity and just passing the lat and long as a param

    im posting my code for if someone might find it useful

    var second = new Intent(this, typeof(image));
                    second.PutExtra("coords", imgID1);
                    StartActivity(second);
    

    and in my new activity I converted the coords to to int using

    public void getco(string co)
            {
                //co = "-29.8311377000678,30.8626617489729|-29.8312837788534,30.8625764695924|-29.831395356685,30.8626905935966|-29.8312667760435,30.8628373001498";
                int i = 0;
                int j = -1;
                int x;
                int y;
                string[] xy = new string[1];
                string[] XY = new string[1];
                string var = Resource.Layout.Main.ToString();
                tv = FindViewById<TextView>(Resource.Id.textView1);
                coords = co;
                s = coords.Trim().Split('|');
                _points.RemoveAll(item => item == null);
                foreach (string part in s)
                {
                    xy = part.Split(',');
                    double dY = Convert.ToDouble(xy[0]);
                    double dX = Convert.ToDouble(xy[1]);
                    if (i <= s.Length-1)
                    {
                        if (i == 0)
                        {
                            sam = s[s.Length-1];
                            XY = sam.Split(',');
                            double dY1 = Convert.ToDouble(XY[0]);
                            double dX1 = Convert.ToDouble(XY[1]);
                            y = Convert.ToInt32((((+dY - dY1) * 1000000) + 400) / 0.6);
                            x = Convert.ToInt32((((+dX - dX1) * 1000000) + 400) / 0.6);
                            string lat = Convert.ToString(y);
                            string lon = Convert.ToString(x);
                            _points.Add(lat + "," + lon);
                            j++;
                            i++;
                        }
                        else
                        { 
                            sam = s[j];
                            XY = sam.Split(',');
                            double dY1 = Convert.ToDouble(XY[0]);
                            double dX1 = Convert.ToDouble(XY[1]);
                            y = Convert.ToInt32((((+dY - dY1) * 1000000) + 400) / 0.6);
                            x = Convert.ToInt32((((+dX - dX1) * 1000000) + 400) / 0.6);
                            string lat = Convert.ToString(y);
                            string lon = Convert.ToString(x);
                            _points.Add(lat + "," + lon);
                            j++;
                            i++;
                        }
                    }
                }
               // Add the closing param
                _points.Add(_points[0]);
            }
    
      protected override void OnDraw(Canvas canvas) // Draw points
            {
                string s = checkpoints();
                float i = float.Parse(s);
                string[] dd = new string[1];
                string[] ee = new string[1];
                base.OnDraw(canvas);
                var path = new Path();
                var paint = new Paint
                {
                    Color = Color.White
                };
                if (i > 0 && i < 2.5)
                {
                    i = 2.6f;
                }
                if (i > 1)
                {
                    dd = _points[0].Split(',');
                    path.MoveTo(((float.Parse(dd[0])) / i), ((float.Parse(dd[1])) / i));
                    foreach (string point in _points)
                    {
                        dd = point.Split(',');
                        path.LineTo(((float.Parse(dd[0])) / i), ((float.Parse(dd[1])) / i));
                    }
                }
                else
                {
                    dd = _points[0].Split(',');
                    path.MoveTo(float.Parse(dd[0]), float.Parse(dd[1]));
                    ee = _points[0].Split(',');
                    foreach (string point in _points)
                    {
                        dd = point.Split(',');
                        path.LineTo(float.Parse(dd[0]), float.Parse(dd[1]));
                    }
                }
    
                paint.SetStyle(Paint.Style.Stroke);
                paint.StrokeWidth = 3f;
                canvas.DrawPath(path, paint);
    
            }
            private string checkpoints() // check if points fit screen size
            {
                string[] ss = new string[1];
                double w = 0;
                double h = 0;
                double w1 = 0;
                double h1 = 0;
                double px = 0;
                double py = 0;
                double result = 0;
    
                DisplayMetrics metrics = Context.Resources.DisplayMetrics;
                double width = metrics.WidthPixels; //[0] x 
                double height = metrics.HeightPixels; //[1] y 
    
                foreach (string s in _points)
                {
                    ss = s.Split(',');
                    w = Convert.ToDouble(ss[0]);
                    h = Convert.ToDouble(ss[1]);
                    if (w >= w1)
                    {
                        w1 = w;
                    }
                    if (h >= h1)
                    {
                        h1 = h;
                    }
    
                }
                if (w1 >= width){
                    px = (w1 / width);
                }
                if (h1 >= height)
                {
                    py = (h1 / height);
                }
                if (py >= px)
                {
                    result = py;
                }
                else
                {
                    result = px;
                }
                return result.ToString();
            }
        }
    
Sign In or Register to comment.