如何在Fuse中建立自定義的UI組件類

當Fuse的默認組件難以滿足我們需求的時候我們就可以通過自建UI組件來在App中使用,具體方法如下:
首先,我們需要引入一個概念——ux:Class"類"屬性:

ux類的建立(ux:Class)

我們通過在UX markup代碼里指定一個節(jié)點的ux:Class屬性來定義一個新的組件類,“類”是一個可以在你的項目中的其它位置,通過實例化來重復多次使用的組件。
ux:Class建立了一個獨立而功能齊全的組件,能被用到項目的任何地方。在類的自身之外是?無法訪問到ux:Names的,如果需要建立一個在某些特定的上下文情況中能有權限訪問到ux:Names的類的話請參看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)

當建立一個自定義類時,在很多情況下,我們需要能夠定義出能實現(xiàn)交互效果的類,這可以通過UX來實現(xiàn),使用的是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}句式來實現(xiàn)。

  • 注意:現(xiàn)在存在一個被稱為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這些元素公共屬性在實例化時是可以直接使用的,也就是是說無須做自定義屬性的,因為生成的實例繼承了類中樣本元素的屬性(已測);
  • 如果你定義類的自定義屬性時使用了與樣本元素的公共屬性集里的名稱,也就是說重名了的話,F(xiàn)use不會提示錯誤,但是你的自定義屬性不會生效(已測),可在此處查到這些元素對應的屬性https://www.fusetools.com/learn/reference

可見量/數(shù)組屬性 Observable/Array properties

如果你想進入一個可見量或數(shù)組以屬性的方式,可以用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)建它的對象的實現(xiàn),包括私有數(shù)據(jù);
⒉ 內部類不為同一包的其他類所見,具有很好的封裝性;
⒊ 使用內部類可以很方便的編寫事件驅動程序;
⒋ 匿名內部類可以方便的定義運行時回調;
好了,普及完了,回歸正題吧!
一個內部類隸屬于一個特定的范圍或作用域,而且對在此作用域中聲明的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在文檔根節(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日
博客被黑,挪窩簡書安家……

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,569評論 19 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,058評論 25 709
  • 國家電網(wǎng)公司企業(yè)標準(Q/GDW)- 面向對象的用電信息數(shù)據(jù)交換協(xié)議 - 報批稿:20170802 前言: 排版 ...
    庭說閱讀 12,423評論 6 13
  • 朝霞漫天始出發(fā),車馬勞頓心卻歡。 群山巍峨風景麗,快步如飛趕路急。 山路崎嶇十八彎,歌聲縈繞徹云間。 狂風驟雨浴吾...
    牧峰閱讀 770評論 2 2
  • 兩周前去了趟地壇公園,聽說那里的杏葉非常漂亮。在門口買了串冰糖葫蘆就去逛了,走到一條兩邊是法國梧桐的小路邊坐著,仰...
    阿溯閱讀 843評論 0 0

友情鏈接更多精彩內容