Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 从Xamarin.Forms中的共享项目中获取特定于平台的自定义视图渲染器中的数据_Android_Xamarin_Xamarin.forms_Custom View - Fatal编程技术网

Android 从Xamarin.Forms中的共享项目中获取特定于平台的自定义视图渲染器中的数据

Android 从Xamarin.Forms中的共享项目中获取特定于平台的自定义视图渲染器中的数据,android,xamarin,xamarin.forms,custom-view,Android,Xamarin,Xamarin.forms,Custom View,我正在使用Xamarin.Forms开发一个移动应用程序。在我的应用程序中,我使用自定义视图实现自定义摄影机。我已成功实现自定义摄影机视图。我现在要做的是,当单击共享项目中的按钮时,我想从特定于平台的自定义视图渲染器中检索一些数据。请参见下面的场景 这是共享项目中的my CameraPage.xaml <?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/20

我正在使用Xamarin.Forms开发一个移动应用程序。在我的应用程序中,我使用自定义视图实现自定义摄影机。我已成功实现自定义摄影机视图。我现在要做的是,当单击共享项目中的按钮时,我想从特定于平台的自定义视图渲染器中检索一些数据。请参见下面的场景

这是共享项目中的my CameraPage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<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">
    <ContentPage.Content>
        <StackLayout Orientation="Vertical">

            <local:CameraPreview x:Name="Camera" Camera="Rear" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" />
            <StackLayout Orientation="Vertical" HorizontalOptions="Center">
                <Button x:Name="buttonCapturePhoto" Text="Capture photo" />
            </StackLayout>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>
在Android项目中,我为摄影机自定义视图创建了渲染器,如下所示

[assembly: ExportRenderer(typeof(MementoApp.Views.CameraPreview), typeof(MementoApp.Droid.CameraPreviewRenderer))]
namespace MementoApp.Droid
{
    public class CameraPreviewRenderer : ViewRenderer<MementoApp.Views.CameraPreview, MementoApp.Droid.CameraPreview>
    {
        CameraPreview cameraPreview;

        public CameraPreview CameraPreview { get { return this.cameraPreview; } }

        public CameraPreviewRenderer(Context context) : base(context)
        {

        }

        protected override void OnElementChanged(ElementChangedEventArgs<MementoApp.Views.CameraPreview> 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);
        }
    }
}
void ButtonCapturePhoto_Clicked(object sender, EventArgs e)
        {

        }
public string Data { get { return "Message from  the Android Project"; } }
Camera.Data //Data would be "Message from the Android Project" and Camera is the custom view.
在该事件中,我想从Android项目中的CameraPreviewRenderer检索数据。例如,我在CameraPreviewRenderer类中创建了如下属性

[assembly: ExportRenderer(typeof(MementoApp.Views.CameraPreview), typeof(MementoApp.Droid.CameraPreviewRenderer))]
namespace MementoApp.Droid
{
    public class CameraPreviewRenderer : ViewRenderer<MementoApp.Views.CameraPreview, MementoApp.Droid.CameraPreview>
    {
        CameraPreview cameraPreview;

        public CameraPreview CameraPreview { get { return this.cameraPreview; } }

        public CameraPreviewRenderer(Context context) : base(context)
        {

        }

        protected override void OnElementChanged(ElementChangedEventArgs<MementoApp.Views.CameraPreview> 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);
        }
    }
}
void ButtonCapturePhoto_Clicked(object sender, EventArgs e)
        {

        }
public string Data { get { return "Message from  the Android Project"; } }
Camera.Data //Data would be "Message from the Android Project" and Camera is the custom view.
在事件内部,我可能会像这样检索该属性

[assembly: ExportRenderer(typeof(MementoApp.Views.CameraPreview), typeof(MementoApp.Droid.CameraPreviewRenderer))]
namespace MementoApp.Droid
{
    public class CameraPreviewRenderer : ViewRenderer<MementoApp.Views.CameraPreview, MementoApp.Droid.CameraPreview>
    {
        CameraPreview cameraPreview;

        public CameraPreview CameraPreview { get { return this.cameraPreview; } }

        public CameraPreviewRenderer(Context context) : base(context)
        {

        }

        protected override void OnElementChanged(ElementChangedEventArgs<MementoApp.Views.CameraPreview> 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);
        }
    }
}
void ButtonCapturePhoto_Clicked(object sender, EventArgs e)
        {

        }
public string Data { get { return "Message from  the Android Project"; } }
Camera.Data //Data would be "Message from the Android Project" and Camera is the custom view.

如何实现这一点?

Xamarin.Forms消息中心是实现这一点的一种方法。只需订阅自定义渲染器类中的事件

protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
    if (e.PropertyName == CameraPreview.DataProperty.PropertyName)
    {
        ... do what you need to do ...
    }
}
另一种方法是在CameraPreview类中创建
Data
属性,而不是CameraPreviewRenderer,然后可以在单击按钮时设置该属性。即

void ButtonCapturePhoto_Clicked(object sender, EventArgs e)
{
    Camera.Data = ...;
}
现在,您将能够在CameraPreviewRenderer类中的
OnElementPropertyChanged
方法中获取
数据

protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
    if (e.PropertyName == CameraPreview.DataProperty.PropertyName)
    {
        ... do what you need to do ...
    }
}
更新:最好的方法是使用事件处理程序。在
CameraPreview
类中,创建一个事件处理程序和方法来调用它:

public event eventHandler<MyDataObject> OnData;

public void InvokeOnData(MyDataObject obj)
{
    OnData?.Invoke(this, obj);
}
然后,您可以这样调用它:

void ButtonCapturePhoto_Clicked(object sender, EventArgs e)
{
    Camera.InvokeOnData(your data);
}
您可以在单击的
按钮拍摄照片
方法中使用,下面是我的演示:

在SharedProject中,定义接口
IGetData

namespace MementoApp
{
    public interface IGetData
    {
        string getData();
    }
}
在Android项目中,实现以下界面:

[assembly: Xamarin.Forms.Dependency(typeof(GetDataImpl))]
namespace MementoApp.Droid
{
    public class GetDataImpl :IGetData
    {
        public string getData()
        {
            //in this method, you can also use other approaches to get the data, like delegate/event/interface.
            CameraPreviewRenderer cpr= new CameraPreviewRenderer(Application.Context);
            cpr.initData();
            return cpr.Data;
        }
    }
}
您的
CameraPreviewRenderer
添加这些(我使用一种方法-
initData
来模拟
数据的生成):

最后,在点击的
按钮中调用它:

private void ButtonCapturePhoto_Clicked(object sender, EventArgs e)
{
    string data = DependencyService.Get<IGetData>().getData();
    System.Diagnostics.Debug.Write("data====="+data);
}
private void按钮已单击拍摄照片(对象发送者,事件参数e)
{
字符串数据=DependencyService.Get().getData();
System.Diagnostics.Debug.Write(“数据===”+数据);
}

可以正确地说,在渲染器中,
CameraPreview-CameraPreview变量不是
MementoApp.Views.CameraPreview
实例?您有两个名为
CameraPreview
的类?尽管我相信消息中心可以做到这一点,但我不太希望它能为他的
CameraView
提供一个干净、可重用且不耦合的解决方案=/是的,我个人在我的应用程序中根本不使用消息中心,我也不使用。我尽我所能避免它。在CameraPreview类中添加数据属性,您指的是共享项目中的CameraPreview类。是吗?是的,类似于您已经设置了
Camera
bindable属性。这样,当属性值更改时,可以在自定义渲染器的OnElementPropertyChanged方法中侦听它