You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin.Forms:共享项目按钮点击时获取平台自定义视图渲染器数据

没问题,我来帮你搞定这个需求!在Xamarin.Forms里实现从共享项目按钮触发、从平台特定的相机渲染器获取数据,核心是通过自定义事件+可绑定属性的方式打通共享代码和平台原生代码的通信,下面是一步步的落地方案:

1. 共享项目:搭建自定义相机视图与交互逻辑

首先得在共享项目里定义一个自定义视图,用来承载相机功能,同时提供触发数据请求的入口和接收数据的通道:

// 共享项目:CustomCameraView.cs
using Xamarin.Forms;

public class CustomCameraView : View
{
    // 定义事件:通知平台渲染器需要获取相机数据
    public event EventHandler RequestData;

    // 可绑定属性:用来接收渲染器返回的相机数据(这里用字节数组举例,你可以改成自己需要的类型)
    public static readonly BindableProperty CapturedDataProperty =
        BindableProperty.Create(nameof(CapturedData), typeof(byte[]), typeof(CustomCameraView), null);

    public byte[] CapturedData
    {
        get => (byte[])GetValue(CapturedDataProperty);
        set => SetValue(CapturedDataProperty, value);
    }

    // 供按钮点击调用的方法,触发数据请求事件
    public void TriggerDataRequest()
    {
        RequestData?.Invoke(this, EventArgs.Empty);
    }
}

接着在你的CameraPage.xaml里引用这个自定义视图,并给按钮绑定点击事件:

<!-- 共享项目:CameraPage.xaml -->
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:YourAppNamespace"
             x:Class="YourAppNamespace.CameraPage">
    <StackLayout Padding="20">
        <!-- 自定义相机视图 -->
        <local:CustomCameraView x:Name="CustomCamera" HeightRequest="300" />
        
        <!-- 触发获取数据的按钮 -->
        <Button Text="获取相机数据" 
                Clicked="OnGetDataClicked"
                Margin="0,20,0,0" />
    </StackLayout>
</ContentPage>

最后在CameraPage.xaml.cs里实现按钮点击的逻辑,触发数据请求并处理返回的数据:

// 共享项目:CameraPage.xaml.cs
public partial class CameraPage : ContentPage
{
    public CameraPage()
    {
        InitializeComponent();
    }

    private void OnGetDataClicked(object sender, EventArgs e)
    {
        // 通知渲染器开始获取数据
        CustomCamera.TriggerDataRequest();
        
        // 拿到返回的数据后做处理(比如显示图片、上传等)
        if (CustomCamera.CapturedData != null)
        {
            Console.WriteLine($"成功获取到相机数据,长度:{CustomCamera.CapturedData.Length}");
            // 这里可以把字节数组转成ImageSource显示在界面上
            // var imageSource = ImageSource.FromStream(() => new MemoryStream(CustomCamera.CapturedData));
        }
    }
}

2. Android平台:实现渲染器并响应数据请求

在Android项目里创建自定义渲染器,监听共享视图的RequestData事件,获取相机数据后返回给共享项目:

// Android项目:CustomCameraViewRenderer.cs
using Android.Content;
using YourAppNamespace;
using YourAppNamespace.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

[assembly: ExportRenderer(typeof(CustomCameraView), typeof(CustomCameraViewRenderer))]
namespace YourAppNamespace.Droid
{
    public class CustomCameraViewRenderer : ViewRenderer<CustomCameraView, Android.Views.View>
    {
        // 替换成你自己的Android相机实现类
        private YourAndroidCamera _camera;

        public CustomCameraViewRenderer(Context context) : base(context)
        {
            // 初始化相机
            _camera = new YourAndroidCamera(context);
        }

        protected override void OnElementChanged(ElementChangedEventArgs<CustomCameraView> e)
        {
            base.OnElementChanged(e);

            // 清理旧元素的事件监听
            if (e.OldElement != null)
            {
                e.OldElement.RequestData -= OnRequestData;
            }

            // 绑定新元素的事件和原生视图
            if (e.NewElement != null)
            {
                SetNativeControl(_camera.GetCameraPreviewView());
                e.NewElement.RequestData += OnRequestData;
            }
        }

        private void OnRequestData(object sender, EventArgs e)
        {
            // 从相机获取数据(比如拍摄照片的字节数组)
            byte[] cameraData = _camera.CapturePhoto();
            
            // 注意:要回到UI线程更新绑定属性
            Context.RunOnUiThread(() =>
            {
                Element.CapturedData = cameraData;
            });
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                // 清理资源和事件监听
                Element.RequestData -= OnRequestData;
                _camera?.Dispose();
            }
            base.Dispose(disposing);
        }
    }
}

3. iOS平台:实现渲染器并响应数据请求

iOS的实现逻辑和Android一致,监听事件、获取数据后返回:

// iOS项目:CustomCameraViewRenderer.cs
using YourAppNamespace;
using YourAppNamespace.iOS;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

[assembly: ExportRenderer(typeof(CustomCameraView), typeof(CustomCameraViewRenderer))]
namespace YourAppNamespace.iOS
{
    public class CustomCameraViewRenderer : ViewRenderer<CustomCameraView, UIView>
    {
        // 替换成你自己的iOS相机实现类
        private YourIOSCamera _camera;

        protected override void OnElementChanged(ElementChangedEventArgs<CustomCameraView> e)
        {
            base.OnElementChanged(e);

            if (e.OldElement != null)
            {
                e.OldElement.RequestData -= OnRequestData;
            }

            if (e.NewElement != null)
            {
                _camera = new YourIOSCamera();
                SetNativeControl(_camera.GetCameraPreviewView());
                e.NewElement.RequestData += OnRequestData;
            }
        }

        private void OnRequestData(object sender, EventArgs e)
        {
            // 从iOS相机获取数据
            byte[] cameraData = _camera.CapturePhoto();
            
            // 回到主线程更新绑定属性
            InvokeOnMainThread(() =>
            {
                Element.CapturedData = cameraData;
            });
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                Element.RequestData -= OnRequestData;
                _camera?.Dispose();
            }
            base.Dispose(disposing);
        }
    }
}

几个关键注意点

  • 线程安全:相机操作通常在后台线程执行,更新共享视图的绑定属性时,一定要切换到UI线程(Android用RunOnUiThread,iOS用InvokeOnMainThread),避免界面卡顿或崩溃。
  • 数据类型灵活调整:如果你的相机数据不是字节数组(比如图片路径、自定义模型),可以直接修改CapturedData的类型,只要保证平台渲染器能返回对应类型即可。
  • 替代方案:如果你不想用可绑定属性,也可以在共享视图里定义一个Action<byte[]>回调,渲染器直接调用这个回调把数据传回去,逻辑会更简洁。

内容的提问来源于stack exchange,提问作者Wai Yan Hein

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:47:37