title: Getting the data from the Custom View Renderer in the platform specific from Shared Project in Xamarin.Forms
body: <p>I am developing a mobile application using Xamarin.Forms. In my application, I am implementing custom camera using a custom view. I have successfully implemented the custom camera view. What I am trying to do now is, I would like to retrieve some data from custom view renderer in the platform-specific when a button is clicked which is inside the shared project. See my scenario below.</p>
  
  <p>This is my CameraPage.xaml in the shared project.</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8" ?&gt;
  &lt;ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
               xmlns:local="clr-namespace:MementoApp.Views;"
               xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
               Title="Capture your moment"
               Padding="0,20,0,0"
               x:Class="MementoApp.Views.CameraPage"&gt;
      &lt;ContentPage.Content&gt;
          &lt;StackLayout Orientation="Vertical"&gt;
  
              &lt;local:CameraPreview x:Name="Camera" Camera="Rear" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" /&gt;
              &lt;StackLayout Orientation="Vertical" HorizontalOptions="Center"&gt;
                  &lt;Button x:Name="buttonCapturePhoto" Text="Capture photo" /&gt;
              &lt;/StackLayout&gt;
          &lt;/StackLayout&gt;
      &lt;/ContentPage.Content&gt;
  &lt;/ContentPage&gt;
  </code></pre>
  
  <p>As you can see, the CameraPreview is the custom view. I also added a button below it.</p>
  
  <p>this is the CameraPreview class</p>
  
  <pre><code>namespace MementoApp.Views
  {
      public enum CameraOptions
      {
          Rear,
          Front
      }
  
      public class CameraPreview : View
      {
          public static readonly BindableProperty CameraProperty = BindableProperty.Create(
              propertyName: "Camera",
              returnType: typeof(CameraOptions),
              declaringType: typeof(CameraPreview),
              defaultValue: CameraOptions.Rear);
  
          public CameraOptions Camera
          {
              get { return (CameraOptions)GetValue(CameraProperty); }
              set { SetValue(CameraProperty, value); }
          }
      }
  }
  </code></pre>
  
  <p>In the Android Project, I created the Renderer for camera custom view like this.</p>
  
  <pre><code>[assembly: ExportRenderer(typeof(MementoApp.Views.CameraPreview), typeof(MementoApp.Droid.CameraPreviewRenderer))]
  namespace MementoApp.Droid
  {
      public class CameraPreviewRenderer : ViewRenderer&lt;MementoApp.Views.CameraPreview, MementoApp.Droid.CameraPreview&gt;
      {
          CameraPreview cameraPreview;
  
          public CameraPreview CameraPreview { get { return this.cameraPreview; } }
  
          public CameraPreviewRenderer(Context context) : base(context)
          {
  
          }
  
          protected override void OnElementChanged(ElementChangedEventArgs&lt;MementoApp.Views.CameraPreview&gt; e)
          {
              base.OnElementChanged(e);
  
              if (Control == null)
              {
                  cameraPreview = new CameraPreview(Context);
                  SetNativeControl(cameraPreview);
              }
  
              if (e.OldElement != null)
              {
                  // Unsubscribe
                  cameraPreview.Click -= OnCameraPreviewClicked;
              }
              if (e.NewElement != null)
              {
                  Control.Preview = Camera.Open((int)e.NewElement.Camera);
  
                  // Subscribe
                  cameraPreview.Click += OnCameraPreviewClicked;
              }
          }
  
          void OnCameraPreviewClicked(object sender, EventArgs e)
          {
              if (cameraPreview.IsPreviewing)
              {
                  cameraPreview.Preview.StopPreview();
                  cameraPreview.IsPreviewing = false;
              }
              else
              {
                  cameraPreview.Preview.StartPreview();
                  cameraPreview.IsPreviewing = true;
              }
          }
  
          protected override void Dispose(bool disposing)
          {
              if (disposing)
              {
                  Control.Preview.Release();
              }
              base.Dispose(disposing);
          }
      }
  }
  </code></pre>
  
  <p>This is the CameraPreview class in the Android Project.</p>
  
  <pre><code>public sealed class CameraPreview : ViewGroup, ISurfaceHolderCallback
      {
          SurfaceView surfaceView;
          ISurfaceHolder holder;
          Camera.Size previewSize;
          IList&lt;Camera.Size&gt; supportedPreviewSizes;
          Camera camera;
          IWindowManager windowManager;
  
          public bool IsPreviewing { get; set; }
  
          public Camera Preview
          {
              get { return camera; }
              set
              {
                  camera = value;
                  if (camera != null)
                  {
                      supportedPreviewSizes = Preview.GetParameters().SupportedPreviewSizes;
                      RequestLayout();
                  }
              }
          }
  
          public CameraPreview(Context context)
              : base(context)
          {
              surfaceView = new SurfaceView(context);
              AddView(surfaceView);
  
              windowManager = Context.GetSystemService(Context.WindowService).JavaCast&lt;IWindowManager&gt;();
  
              IsPreviewing = false;
              holder = surfaceView.Holder;
              holder.AddCallback(this);
          }
  
          protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
          {
              int width = ResolveSize(SuggestedMinimumWidth, widthMeasureSpec);
              int height = ResolveSize(SuggestedMinimumHeight, heightMeasureSpec);
              SetMeasuredDimension(width, height);
  
              if (supportedPreviewSizes != null)
              {
                  previewSize = GetOptimalPreviewSize(supportedPreviewSizes, width, height);
              }
          }
  
          protected override void OnLayout(bool changed, int l, int t, int r, int b)
          {
              var msw = MeasureSpec.MakeMeasureSpec(r - l, MeasureSpecMode.Exactly);
              var msh = MeasureSpec.MakeMeasureSpec(b - t, MeasureSpecMode.Exactly);
  
              surfaceView.Measure(msw, msh);
              surfaceView.Layout(0, 0, r - l, b - t);
          }
  
          public void SurfaceCreated(ISurfaceHolder holder)
          {
              try
              {
                  if (Preview != null)
                  {
                      Preview.SetPreviewDisplay(holder);
                  }
              }
              catch (Exception ex)
              {
                  System.Diagnostics.Debug.WriteLine(@"           ERROR: ", ex.Message);
              }
          }
  
          public void SurfaceDestroyed(ISurfaceHolder holder)
          {
              if (Preview != null)
              {
                  Preview.StopPreview();
              }
          }
  
          public void SurfaceChanged(ISurfaceHolder holder, Android.Graphics.Format format, int width, int height)
          {
              var parameters = Preview.GetParameters();
              parameters.SetPreviewSize(previewSize.Width, previewSize.Height);
              RequestLayout();
  
              switch (windowManager.DefaultDisplay.Rotation)
              {
                  case SurfaceOrientation.Rotation0:
                      camera.SetDisplayOrientation(90);
                      break;
                  case SurfaceOrientation.Rotation90:
                      camera.SetDisplayOrientation(0);
                      break;
                  case SurfaceOrientation.Rotation270:
                      camera.SetDisplayOrientation(180);
                      break;
              }
  
              Preview.SetParameters(parameters);
              Preview.StartPreview();
              IsPreviewing = true;
          }
  
          Camera.Size GetOptimalPreviewSize(IList&lt;Camera.Size&gt; sizes, int w, int h)
          {
              const double AspectTolerance = 0.1;
              double targetRatio = (double)w / h;
  
              if (sizes == null)
              {
                  return null;
              }
  
              Camera.Size optimalSize = null;
              double minDiff = double.MaxValue;
  
              int targetHeight = h;
              foreach (Camera.Size size in sizes)
              {
                  double ratio = (double)size.Width / size.Height;
  
                  if (Math.Abs(ratio - targetRatio) &gt; AspectTolerance)
                      continue;
                  if (Math.Abs(size.Height - targetHeight) &lt; minDiff)
                  {
                      optimalSize = size;
                      minDiff = Math.Abs(size.Height - targetHeight);
                  }
              }
  
              if (optimalSize == null)
              {
                  minDiff = double.MaxValue;
                  foreach (Camera.Size size in sizes)
                  {
                      if (Math.Abs(size.Height - targetHeight) &lt; minDiff)
                      {
                          optimalSize = size;
                          minDiff = Math.Abs(size.Height - targetHeight);
                      }
                  }
              }
  
              return optimalSize;
          }
      }
  </code></pre>
  
  <p>What I am trying to do now is I want to retrieve some data from the CameraPreviewRenderer from the SharedProject when the "Capture" button is clicked. I created the event for capture button like this in the CameraPage.xaml.cs in the shared project like this.</p>
  
  <pre><code>void ButtonCapturePhoto_Clicked(object sender, EventArgs e)
          {
  
          }
  </code></pre>
  
  <p>Inside that event, I want to retrieve the data from the CameraPreviewRenderer in the Android project. For example, I created a property in the CameraPreviewRenderer class like this.</p>
  
  <pre><code>public string Data { get { return "Message from  the Android Project"; } }
  </code></pre>
  
  <p>Inside the event like, maybe I would retrieve that property like this.</p>
  
  <pre><code>Camera.Data //Data would be "Message from the Android Project" and Camera is the custom view.
  </code></pre>
  
  <p>How can I achieve this?</p>