如何在Fuse中建立自定义的UI组件类

当Fuse的默认组件难以满足我们需求的时候我们就可以通过自建UI组件来在App中使用,具体方法如下:
首先,我们需要引入一个概念——ux:Class"类"属性:

ux类的建立(ux:Class)

我们通过在UX markup代码里指定一个节点的ux:Class属性来定义一个新的组件类,“类”是一个可以在你的项目中的其它位置,通过实例化来重复多次使用的组件。
ux:Class建立了一个独立而功能齐全的组件,能被用到项目的任何地方。在类的自身之外是�无法访问到ux:Names的,如果需要建立一个在某些特定的上下文情况中能有权限访问到ux:Names的类的话请参看ux:InnerClass区。
Example
下面的代码建立了一个从Text元素继承的被称为Header的类:
<Text ux:Class="Header" FontSize="22" />
他能被实例化,就像其它的Fuse标准内建元素一样。
<Header>Welcome</Header>
在上述例子中,Header类将成为一个来自于但不同于Text类的类, 尽管所有的可用属性都来自于Text。注意,类可以放在单独的.ux文件中定义,通常情况下也一般是这么来定义的。
自定义类也可以做到很复杂的效果,如果你有需求的话:
<pre>
<Image ux:Class="BurgerIcon">
<MultiDensityImageSource>
<FileImageSource File="Burger.png" Density="1"/>
<FileImageSource File="Burger.png@2x.png" Density="2"/>
</MultiDenistyImageSoruce>
</Image>

<Panel>
<BurgerIcon />
</Panel>
</pre>
他们可以有自己的逻辑性"logic",包括使用触发器、动作、和JavaScript等(triggers, actions)。
注意:使用ux:Class建立的类�映射到了真正的Uno类里边Uno-classes,可以理解成为原生的了吧:
如:
<Panel ux:Class="MyPanel"/>
等同于下面的Uno类Uno-class:
public class MyPanel : Panel { ... }

ux类的属性定义(ux:Property)

当建立一个自定义类时,在很多情况下,我们需要能够定义出能实现交互效果的类,这可以通过UX来实现,使用的是ux:Property语法,这样我们就可以在实例化时用属性来在有限的范围内控制自己所写的类了。
MyButton.ux:
<pre>
<Panel ux:Class="MyButton" Text="Click me!"
Fill="#f00" TextColor="#000" CornerRadius="10">
<string ux:Property="Text"/>
<float4 ux:Property="CornerRadius" />
<Brush ux:Property="Fill" />
<float4 ux:Property="TextColor"/>
<Text Alignment="Center" TextColor="{Property this.TextColor}" Value="{Property this.Text}"/>
<Rectangle Layer="Background" CornerRadius="{Property this.CornerRadius}" Fill="{Property this.Fill}" />
</Panel>
</pre>

上例我们建立了一个称为MyButton的类,定义了并陈列出四个自定义的属性(Text, CornerRadius, Fill and TextColor)。这些属性能被梆定到我们的类ux:Class之内,使用{Property this.PropName}句式来实现。

  • 注意:现在存在一个被称为this的隐藏名称,我们一般在{Property this.PropName}句式之内使用,此名称常用来引用ux:Class里的最顶级根元素。(易咸注:其实个人觉得可以理解为面向对象里边的this指针,this指向的是实例化时的对象本身)。

实例化时自定义ux类的属性传递(ux:Property)

当我们实例化了我们自己定义的类的时候,就可以直接访问变量了。
MainView.ux:
<pre>
<App>
<MyButton CornerRadius="20" Text="MyText"
TextColor="#fff" Width="200" Height="50">
<LinearGradient ux:Binding="Fill">
<GradientStop Color="#0f0" Offset="0" />
<GradientStop Color="#00f" Offset="1" />
</LinearGradient>
</MyButton>
</App>
</pre>

你可以使用ux:Binding来设置或访问父元素引用类别的属性,像笔刷Brush这类,在上例中,我们建立了一个线性渐变LinearGradient,接着又把它梆定到父元素的Fill属性上,从而看起来像是直接作为Fill使用的。

我们做一个图来分析一下

通过此图我们不难看出:

  • 定义类时使用的元素样本是可以设置默认值的,当实例化时如果没有设置这个属性的值的话,会使用在类中的默认值来实例化类(已测,公共属性与自定义属性都支持默认值的设置);
  • 像Width和Height这些元素公共属性在实例化时是可以直接使用的,也就是是说无须做自定义属性的,因为生成的实例继承了类中样本元素的属性(已测);
  • 如果你定义类的自定义属性时使用了与样本元素的公共属性集里的名称,也就是说重名了的话,Fuse不会提示错误,但是你的自定义属性不会生效(已测),可在此处查到这些元素对应的属性https://www.fusetools.com/learn/reference

可见量/数组属性 Observable/Array properties

如果你想进入一个可见量或数组以属性的方式,可以用object类型,如下例:
<pre>
<Panel ux:Class="ListView">
<object ux:Property="ListItems" />
<StackPanel>
<Each Items="{Property this.ListItems}">
<Panel Padding="10">
<Text Value="{}" />
</Panel>
</Each>
</StackPanel>
</Panel>
<JavaScript>
exports.items = ["Foo", "Bar", "Baz"];
</JavaScript>
<ListView ListItems="{items}" />
</pre>

ux内部类(ux:InnerClass)

内部类的定义
内部类是定义在其他类内部的类。它几乎可以处于类内部任何位置,可以与实例变量处于同一级,或处于方法之内,甚至是一个表达式的一部分!
优点如下
⒈ 内部类对象可以访问创建它的对象的实现,包括私有数据;
⒉ 内部类不为同一包的其他类所见,具有很好的封装性;
⒊ 使用内部类可以很方便的编写事件驱动程序;
⒋ 匿名内部类可以方便的定义运行时回调;
好了,普及完了,回归正题吧!
一个内部类隶属于一个特定的范围或作用域,而且对在此作用域中声明的ux:Names具有访问权限。内部类仅仅只能用在声明过他的作用域中。
<pre>
<App Theme="Basic">
<Button ux:InnerClass="ActivateButton" ux:Name="btn" Margin="10">
<Clicked>

<Set highlight.LayoutMaster="btn" />
</Clicked>
</Button>
<StackPanel>
<ActivateButton Text="Option A" ux:Name="defaultOption"/>
<ActivateButton Text="Option B" />
<ActivateButton Text="Option C" />
<Rectangle Fill="Red" ux:Name="highlight" Margin="-5" LayoutMaster="defaultOption">
<LayoutAnimation>
<Move RelativeTo="PositionChange" X="1" Y="1" Duration="0.4" Easing="BackOut" />
</LayoutAnimation>
</Rectangle>
</StackPanel>
</App>
</pre>

ux文件包含(ux:Include)

你可以插入一个UX文件中的内容到另外一个UX文件中,使用ux:Include。
上面例子,ux:InnerClass 能被分开成单独的文件,分离后的主文件大致如下:
<pre>
<App Theme="Basic">
<ux:Include File="ActivateButton.ux" />
<StackPanel>
<ActivateButton Text="Option A" ux:Name="defaultOption"/>
...
</StackPanel>
</App>
</pre>
需要引用的代码放到ActivateButton.ux中:
<pre>
<Button ux:InnerClass="ActivateButton" ux:Name="btn" Margin="10">
<Clicked>

<Set highlight.LayoutMaster="btn" />
</Clicked>
</Button>
</pre>
需要注意的是,包含的文件不能有ux:Class在文档根节点,那样的话将会在你的项目中建立基于类生成的两个实例,可是,包含文件能指定ux:InnerClass。这将建立一个内部类的本地版本,在每一个包含他的位置。

附:
英文原文:https://www.fusetools.com/learn/fuse#creating-custom-ui-components
高级部分参看,建立一个新类
https://www.fusetools.com/learn/guides/ux-markup-creating-new-classes
属性与梆定Properties and bindings
https://www.fusetools.com/learn/guides/ux-markup-properties-and-bindings
使用你自己的Uno类Using your own Uno classes
https://www.fusetools.com/learn/guides/ux-markup-using-your-own-classes

Tag:Fuse, Fuseapp, Fusetools, native app
发布时间:2016年05月10日
博客被黑,挪窝简书安家……

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,277评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,689评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,624评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,356评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,402评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,292评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,135评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,992评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,429评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,636评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,785评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,492评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,092评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,723评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,858评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,891评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,713评论 2 354

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,654评论 18 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,099评论 25 707
  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 10,967评论 6 13
  • 朝霞漫天始出发,车马劳顿心却欢。 群山巍峨风景丽,快步如飞赶路急。 山路崎岖十八弯,歌声萦绕彻云间。 狂风骤雨浴吾...
    牧峰阅读 696评论 2 2
  • 两周前去了趟地坛公园,听说那里的杏叶非常漂亮。在门口买了串冰糖葫芦就去逛了,走到一条两边是法国梧桐的小路边坐着,仰...
    阿溯阅读 767评论 0 0