0

我在 Xamarin Forms 中有一张图片。我想使用原生 android 功能与这个图像进行交互。例如,当点击图像时,我想知道点击图像位置的 x,y 坐标。我可以使用 Android ImageView 但我不确定如何将 Xamarin Forms 图像转换为 Android ImageView

[assembly: ExportRenderer(typeof(Image), typeof(FloorplanImageRenderer))]
namespace EmployeeApp.Droid.Platform
{

  public class FloorplanImageRenderer : ImageRenderer
  {
        protected override void OnElementChanged(ElementChangedEventArgs<Image> e)
        {
            if (Control == null)
            {

                var imageView = (ImageView)e.NewElement; // This is not right

            }

            base.OnElementChanged(e);
        }
   }
}
4

1 回答 1

1

但控制是空的....

不,它不应该为空。回到您的问题,我认为首先,您需要在 PCL 中将触摸事件附加到图像控件,并创建一个属性以在触摸图像时保存坐标。我认为在您的代码中:

[assembly: ExportRenderer(typeof(Image), typeof(FloorplanImageRenderer))]

我认为Image这里应该是您的自定义图像控件,它继承自 PCL 中的图像。

为触摸事件创建一个接口:

public interface IFloorplanImageController
{
    void SendTouched();
}

为图像创建自定义控件:

 public class FloorplanImage : Image, IFloorplanImageController
 {
     public event EventHandler Touched;

     public void SendTouched()
     {
         Touched?.Invoke(this, EventArgs.Empty);
     }

     public Tuple<float, float> TouchedCoordinate
     {
         get { return (Tuple<float, float>)GetValue(TouchedCoordinateProperty); }
         set { SetValue(TouchedCoordinateProperty, value); }
     }

     public static readonly BindableProperty TouchedCoordinateProperty =
         BindableProperty.Create(
             propertyName: "TouchedCoordinate",
             returnType: typeof(Tuple<float, float>),
             declaringType: typeof(FloorplanImage),
             defaultValue: new Tuple<float, float>(0, 0),
             propertyChanged: OnPropertyChanged);

     public static void OnPropertyChanged(BindableObject bindable, object oldValue, object newValue)
     {
     }
 }

实现自定义渲染器:

[assembly: ExportRenderer(typeof(FloorplanImage), typeof(FloorplanImageRenderer))]

namespace EmployeeApp.Droid.Platform
{
    public class FloorplanImageRenderer : ImageRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Image> e)
        {
            base.OnElementChanged(e);

            if (e.NewElement != null)
            {
                if (Control != null)
                {
                    Control.Clickable = true;
                    Control.SetOnTouchListener(ImageTouchListener.Instance.Value);
                    Control.SetTag(Control.Id, new JavaObjectWrapper<FloorplanImage> { Obj = Element as FloorplanImage });
                }
            }
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (Control != null)
                {
                    Control.SetOnTouchListener(null);
                }
            }

            base.Dispose(disposing);
        }

        private class ImageTouchListener : Java.Lang.Object, Android.Views.View.IOnTouchListener
        {
            public static readonly Lazy<ImageTouchListener> Instance = new Lazy<ImageTouchListener>(
                () => new ImageTouchListener());

            public bool OnTouch(Android.Views.View v, MotionEvent e)
            {
                var obj = v.GetTag(v.Id) as JavaObjectWrapper<FloorplanImage>;
                var element = obj.Obj;
                var controller = element as IFloorplanImageController;
                if (e.Action == Android.Views.MotionEventActions.Down)
                {
                    var x = e.GetX();
                    var y = e.GetY();
                    element.TouchedCoordinate = new Tuple<float, float>(x, y);
                    controller?.SendTouched();
                }
                else if (e.Action == Android.Views.MotionEventActions.Up)
                {
                }
                return false;
            }
        }
    }

    public class JavaObjectWrapper<T> : Java.Lang.Object
    {
        public T Obj { get; set; }
    }
}

像这样使用这个控件:

<local:FloorplanImage HeightRequest="300" x:Name="image" WidthRequest="300"
                      Aspect="AspectFit"  Touched="image_Touched" />

后面的代码:

private void image_Touched(object sender, EventArgs e)
{
    var cor = image.TouchedCoordinate;
}
于 2017-04-13T08:40:17.740 回答