美文网首页
如何在Fuse中建立自定义的UI组件类

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

作者: 衣咸 | 来源:发表于2017-01-05 15:09 被阅读34次

当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日
博客被黑,挪窝简书安家……

相关文章

  • UX Markup语言之如何建立一个新的类

    衣咸注:前面我们在《如何在Fuse中建立自定义的UI组件类》这篇文章有讲过如何建立一个自定义的组件类,如果说前文讲...

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

    当Fuse的默认组件难以满足我们需求的时候我们就可以通过自建UI组件来在App中使用,具体方法如下:首先,我们需要...

  • UX Markup语言之如何使用自定义的新类

    在Fuse中的UX Markup语言中建立你自己Uno类,然后声明式地使用这些自定义类是相当容易的。 一个简单的例...

  • 【译】Fuse入门(三)

    UI 组件 Fuse里有大量现成的UI组件可以用来构建用户界面(User interface)。 在UX文件里,添...

  • Android学习日记

    Day 7 Title UI常用组件basicView android系统中的所有UI类都是建立在View和Vie...

  • 自定义组件

    # 自定义组件 ​ *Android提供了一套复杂而强大的组件化模型来建立你自己的UI。其依赖于基本的布局类:Vi...

  • 1:Activity Window View关系

    View:主要是用于绘制我们想要的结果,是一个最基本的UI组件。Android系统中的所有UI类都是建立在View...

  • Android 进阶之 View 的绘制(一)

    自定义 View 之基础知识 1. View 类简介 View 类是 Android 中各种组件的基类,如:Vie...

  • Flutter(三) 自定义组件、MaterialApp和Sca

    1. 自定义组件 在flutter中自定义组件就是自定义一个类,这个类需要继承StatelessWidget/St...

  • 组件化开发

    一.组件化介绍 组件化模块划分 基础组件: 宏定义/自定义分类/自定义工具类功能组件: 项目中常用功能,如:定位/...

网友评论

      本文标题:如何在Fuse中建立自定义的UI组件类

      本文链接:https://www.haomeiwen.com/subject/lrszvttx.html