當Fuse的默認組件難以滿足我們需求的時候我們就可以通過自建UI組件來在App中使用捺檬,具體方法如下:
首先病线,我們需要引入一個概念——ux:Class
"類"屬性:
ux類的建立(ux:Class)
我們通過在UX markup代碼里指定一個節(jié)點的ux:Class
屬性來定義一個新的組件類经磅,“類”是一個可以在你的項目中的其它位置孵奶,通過實例化來重復多次使用的組件剥纷。
ux:Class
建立了一個獨立而功能齊全的組件抒钱,能被用到項目的任何地方。在類的自身之外是?無法訪問到ux:Name
s的鼎天,如果需要建立一個在某些特定的上下文情況中能有權限訪問到ux:Name
s的類的話請參看ux:InnerClass
區(qū)舀奶。
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"化借,包括使用觸發(fā)器、動作捡多、和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)
內部類的定義
內部類是定義在其他類內部的類喜命。它幾乎可以處于類內部任何位置沟沙,可以與實例變量處于同一級,或處于方法之內壁榕,甚至是一個表達式的一部分矛紫!
優(yōu)點如下
⒈ 內部類對象可以訪問創(chuàng)建它的對象的實現,包括私有數據牌里;
⒉ 內部類不為同一包的其他類所見颊咬,具有很好的封裝性;
⒊ 使用內部類可以很方便的編寫事件驅動程序牡辽;
⒋ 匿名內部類可以方便的定義運行時回調喳篇;
好了,普及完了态辛,回歸正題吧麸澜!
一個內部類隸屬于一個特定的范圍或作用域,而且對在此作用域中聲明的ux:Name
s具有訪問權限因妙。內部類僅僅只能用在聲明過他的作用域中痰憎。
<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
在文檔根節(jié)點蜗细,那樣的話將會在你的項目中建立基于類生成的兩個實例裆操,可是,包含文件能指定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
發(fā)布時間:2016年05月10日
博客被黑缎岗,挪窩簡書安家……