游乐游手机版
首页/AI教程/文章详情

自定义渲染器开发教程第二部分

时间:2026-05-30 09:09
自定义渲染器入门:从HelloRenderers开始 先来介绍一下HelloRenderers这个示例程序。它的核心目标非常明确——就是让你直观地了解,编写一个最简单的自定义渲染器究竟需要完成哪些步骤。在这个示例中,我们定义了一个名为HelloView的新视图,它继承自View,唯一的功能就是在屏幕

自定义渲染器入门:从HelloRenderers开始

先来介绍一下HelloRenderers这个示例程序。它的核心目标非常明确——就是让你直观地了解,编写一个最简单的自定义渲染器究竟需要完成哪些步骤。在这个示例中,我们定义了一个名为HelloView的新视图,它继承自View,唯一的功能就是在屏幕上显示一段固定的文本字符串。

首先来看PCL(可移植类库)中的完整代码,整个HelloView.cs文件的内容极其简洁:

using Xamarin.Forms;
namespace HelloRenderers
{
    public class HelloView : View
    {
    }
}

是的,仅仅只有一行类定义。不过有一个关键细节需要注意:这个类被声明为public。你可能会疑惑,它只用在PCL项目中,为什么必须公开?实际上,它必须对各个平台组件可见,否则后续的渲染器将无法找到它。

HelloRenderers的PCL项目甚至没有单独定义页面类,而是直接在App.cs中将一个HelloView对象居中显示:

namespace HelloRenderers
{
    public class App : Application
    {
        public App()
        {
            MainPage = new ContentPage
            {
                Content = new HelloView
                {
                    VerticalOptions = LayoutOptions.Center,
                    HorizontalOptions = LayoutOptions.Center
                }
            };
        }
    }
}

这段代码运行起来不会产生任何错误,但你将在屏幕上看到一片空白。原因很简单:此时的HelloView只是一个完全透明且没有任何绘制内容的视图,缺少相应的渲染器来告诉它应该以何种方式呈现。

关键点就在这里:当Xamarin.Forms应用启动时,它会通过.NET反射扫描所有程序集,寻找标注了ExportRenderer特性的位置。这个特性就像信标一样,告诉框架:“嘿,这里有一个自定义渲染器,可以为特定的Xamarin.Forms元素提供渲染支持”。

接下来看看iOS项目中的HelloViewRenderer.cs文件。请注意在using语句之后,紧接着就是ExportRenderer特性。由于它是程序集级别的特性,因此必须放在命名空间声明的外部。它的含义非常直接:“HelloView这个类,由HelloViewRenderer这个渲染器负责渲染”:

using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
using UIKit;
using HelloRenderers;
using HelloRenderers.iOS;

[assembly: ExportRenderer(typeof(HelloView), typeof(HelloViewRenderer))]
namespace HelloRenderers.iOS
{
    public class HelloViewRenderer : ViewRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs args)
        {
            base.OnElementChanged(args);
            if (Control == null)
            {
                UILabel label = new UILabel
                {
                    Text = "Hello from iOS!",
                    Font = UIFont.SystemFontOfSize(24)
                };
                SetNativeControl(label);
            }
        }
    }
}

这个HelloViewRenderer类必须公开,它继承自泛型类ViewRenderer。两个泛型参数中,第一个TView对应Xamarin.Forms中的类(也就是HelloView),第二个TNativeView对应iOS平台的原生控件类型。在iOS上,显示文本的标准组件是UIKit命名空间下的UILabel,这里正是选用了它。泛型参数相当于在声明:“一个HelloView对象,实际上会被渲染成一个iOS的UILabel对象”。

渲染器的核心工作在于重写OnElementChanged方法。当HelloView对象被创建时,该方法就会被调用,它的职责就是创建那个真正用于显示内容的原生控件。

OnElementChanged的实现中,首先检查Control属性是否为null。这个Control属性由ViewRenderer定义,类型就是泛型参数中的TNativeView,因此在iOS项目中它是UILabel类型。第一次调用时,Control肯定为null,此时需要创建一个新的UILabel对象,设置好文本和字体大小,然后通过SetNativeControl方法将其注册进去。此后,Control属性就指向这个已创建的UILabel

文件顶部的using指令分为三组:Xamarin.Forms命名空间用于编写ExportRenderer特性;Xamarin.Forms.Platform.iOS用于引用ViewRendererUIKit则用于使用UILabel。最后还有HelloRenderersHelloRenderers.iOS,仅仅是因为ExportRenderer特性中的两个类型引用需要它们。这种为了一个引用而专门引入一个命名空间的做法确实有些繁琐。不过有一个小技巧:你可以直接在特性中使用完全限定名,从而省去这两个using语句。

接下来看看Android版本。Android项目中的HelloViewRenderer.cs文件就采用了这种完全限定名的写法:

using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using Android.Util;
using Android.Widget;

[assembly: ExportRenderer(typeof(HelloRenderers.HelloView), typeof(HelloRenderers.Droid.HelloViewRenderer))]
namespace HelloRenderers.Droid
{
    public class HelloViewRenderer : ViewRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs args)
        {
            base.OnElementChanged(args);
            if (Control == null)
            {
                SetNativeControl(new TextView(Context)
                {
                    Text = "Hello from Android!"
                });
                Control.SetTextSize(ComplexUnitType.Sp, 24);
            }
        }
    }
}

这个渲染器同样继承自Android版本的ViewRenderer。泛型参数表明,HelloView在Android上由TextView来呈现。同样,在第一次调用OnElementChangedControlnull。这里直接创建TextView并调用SetNativeControl,一气呵成。注意TextView的构造函数需要一个Android的Context对象,该对象可以通过OnElementChanged方法的参数获取。

调用完SetNativeControl之后,Control属性就获得了实际的TextView对象。然后通过这个Control调用SetTextSize方法设置字号。在Android中,文本尺寸有多种缩放单位,ComplexUnitType.Sp代表“缩放像素”,这也是Xamarin.Forms处理Label字体大小时的兼容方式。

最后是UWP平台的实现:

using Xamarin.Forms.Platform.UWP;
using Windows.UI.Xaml.Controls;

[assembly: ExportRenderer (typeof(HelloRenderers.HelloView), typeof(HelloRenderers.UWP.HelloViewRenderer))]
namespace HelloRenderers.UWP
{
    public class HelloViewRenderer : ViewRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs args)
        {
            base.OnElementChanged(args);
            if (Control == null)
            {
                SetNativeControl(new TextBlock
                {
                    Text = "Hello from the UWP!",
                    FontSize = 24,
                });
            }
        }
    }
}

在所有Windows平台上,HelloView最终由Windows.UI.Xaml.Controls命名空间中的TextBlock来渲染。Windows Phone(WinPhone)和Windows标准项目中的写法大同小异,区别只在于命名空间以及显示的文本内容。

2019_06_03_131710

运行效果如上图所示。可以看到,通过HelloView对象上设置的HorizontalOptionsVerticalOptions属性,文本被完美居中在屏幕中央。但请注意,你无法在这个HelloView上直接设置HorizontalTextAlignmentVerticalTextAlignment,因为这些属性是Label类特有的,并非View基类提供的。如果希望将HelloView升级为一个功能完善的文本视图,下一步就需要开始向HelloView类中添加自定义属性了。下一篇内容,我们将深入探讨如何实现这一目标。

来源:https://developer.aliyun.com/article/704433
上一篇MARA AI酒店评价管理软件助力提升在线声誉与满意度 下一篇Claude Code半年使用复盘:命令、搭档与两个坑
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
大科学与AI时代知识传承的可持续科研策略
AI教程 · 2026-05-30

大科学与AI时代知识传承的可持续科研策略

科学研究正在以前所未有的速度向前推进,这一点已成为广泛共识。然而,与此同时,一个潜在的危机也在悄然加剧——那些至关重要的知识正在不断流失。大量阴性研究结果始终未能公之于众,资深研究员退休时带走的隐性经验无法有效传承,而知识保存工作长期陷入碎片化的困境。这直接导致了科研资源的浪费、重复试错成本居高不下

高效在线专业AcademicHelp智能学术文章改写实用工具
AI教程 · 2026-05-30

高效在线专业AcademicHelp智能学术文章改写实用工具

AcademicHelp Paraphraser是什么 提到AcademicHelp Paraphraser,相信不少同学已经有所了解——它是由AcademicHelp net团队精心打造的一款AI改写工具。AcademicHelp net这个平台其实已有多年积累,早在2011年就已上线,最初专注于

AIWCLOUD免备案CDN过移动屏蔽不限内容架构全球边缘计算
AI教程 · 2026-05-30

AIWCLOUD免备案CDN过移动屏蔽不限内容架构全球边缘计算

免备案CDN基于全球分布式节点与智能路由优化,结合BBR拥塞控制、QUIC协议、分层缓存及边缘安全防护,提供跨境加速与合规保障。边缘可编程与AI推理能力进一步扩展平台价值,为企业全球化布局构建高性能数字基础设施。

AI工具快速提升专业沟通效果
AI教程 · 2026-05-30

AI工具快速提升专业沟通效果

Professionalize It To Me 产品介绍 在职场沟通中,如何用一句话说得既得体又有分量?很多人明明肚子里有料,一写邮件就变味。Professionalize It To Me 正是为解决这一痛点而生——它能在30秒内,把你的草稿改写成专业水准的邮件或消息,无需注册即可立即上手试用。

未来科研中AI写作如何引领潮流
AI教程 · 2026-05-30

未来科研中AI写作如何引领潮流

对于科研工作者而言,最令人困扰的莫过于被海量文献和数据淹没,论文撰写的时间压力常常抑制了创造性思维的迸发。近年来,越来越多人开始尝试AI写作助手——这股科技浪潮,是否真能为科研开辟一条全新路径? 趣味探索:AI的崛起 一项2023年的研究表明,使用AI写作助手的科研人员,论文撰写效率提升了30%以上