UI Components
UI组件
Fuse附带了许多可用于构建用户界面的UI组件。在UX中,您可以通过将UI组件包含在标记中来添加它们:
<Image File =“MyImage.png”/>
<Rectangle Width =“50”Height =“50”Fill =“#888”/>
<Text> Hello world!</ Text>
注意,只是因为某物被包含在标签中,并不一定意味着它必须是一个UI组件。UX对其他概念也使用标签,例如Triggers和Actions。
Text
这里是一个微小的应用程序,呈现文本:
<App>
<Text> Hello,world!</ Text>
</ App>
这是伟大的,但当你有更长的文本段落,如Lorem Ipsum,你最有可能想要启用字包装。在Fuse中,这是通过Text
控件上的TextWrapping
属性来完成的:
<Text TextWrapping =“Wrap”> Lorem Ipsum(...)</ Text>
如果你仍然发现包装文本仍然很难显示你想要的所有内容,你可能想考虑将内容添加到ScrollView或更改FontSize。TextWrapping
可以设置为Wrap
或NoWrap
(默认)。
字体
您可以从包含TrueType字体的ttf文件导入字体。由于字体通常在整个应用程序中引用,因此最好简单地为其创建一个 全局资源。
<App>
<Font File =“Roboto-Medium.ttf”ux:Global =“Medium”/>
<Font File =“Roboto-Light.ttf”ux:Global =“Light”/>
<StackPanel>
<Text Font =“Light”> Roboto Light </ Text>
<Text Font =“Medium”> Roboto Medium </ Text>
<Text Font =“Light”> Roboto Light再次</ Text>
</ StackPanel>
</ App>
在此示例中,字体位于与相关UX文件相同的目录中。这种导入字体的方式确保字体在整个项目中可用,并且只加载一次。
iOS和Android都支持使用多字节字符集的文本呈现。这意味着emojis在设备上工作精细渲染。
Note!目前有一些问题使用桌面预览呈现多字节字符集。不要惊讶,如果桌面渲染不匹配设备呈现100%。这是一个正在处理的问题。
文本属性
为了进一步控制如何渲染文本,可以设置TextAlignment
,TextColor
,FontSize
和LineSpacing
:
<Text TextColor =“#999”>左</ Text>
<Text TextAlignment =“Center”>中心</ Text>
<Text FontSize =“24”TextAlignment =“Right”> Right </ Text>
<Text LineSpacing =“10”>
多
线
</ Text>
在本示例中,第一个文本元素将左对齐,因为这是默认值,并且其颜色设置为中间浅灰色。第二个文本将居中对齐。第三个将右对齐,并具有较大的字体。第四个将跨越两条线,其间有10个空间。TextAlignment'的有效值为
Left(默认),
Right和
Center`。
Number
虽然文本是在大多数情况下,你可以使用Number
来显示一个格式化的数值。
通过“Format”属性指定的格式必须是标准数字格式字符串的形式。
Number
当前支持的唯一格式是F
,它截断要显示的小数位数。
下面的代码将渲染3.141
:
|
图片
保险丝支持本地显示PNG和JPEG文件(在RGB颜色空间中)。显示图像:
<App>
<Image File =“FuseLogo.png”/>
</ App>
此代码假定文件FuseLogo.png
与UX文件存在于同一目录中。如果你想从互联网加载图像的内容,只需:
<Image Url =“http:// path_to_image”/>
Note!如果你是从web开发人员的背景,你可能习惯于分配一个URL到src属性。虽然
Image有一个
Source属性,它用于为一个图像分配一个
Resource。在这个上下文中,这个“Resource”是一个“HttpImageSource”,但是它是为你自动在封面后面创建的,所以坚持使用
Url`-property从网页加载内容。
###来自资源的图像内容
对于其他方法加载图像数据的一个小例子,这里是一个小例子,也使用JavaScript中的数据绑定:
<FileImageSourceux:Key =“pic2”File =“Images / Image2.jpg”/>
<StackPanel>
<JavaScript>
module.exports = {
imageResource:“pic2”,
url:“http://somewhereontheinternet/Cute-Cat.jpg”
}}
</ JavaScript>
<Image File =“Images / Image1.jpg”/>
<Image Source =“{DataToResource imageResource}”/>
<Image Url =“{url}”/>
</ StackPanel>
此代码将显示三个图像堆叠在彼此的顶部。最上面的图像将作为项目的一部分的文件提取。在顶部,我们通过创建一个FileImageSource
来引用一个文件,我们使用DataToResource
绑定到一个图像。这将从它从JavaScript获取的键查找资源。我们还得到一个图片在网络上的URL并绑定到一个图像'的
Url`属性。如果这看起来很复杂,不要担心:我们稍后将更多地看看数据绑定和JavaScript。
###图像颜色
可以通过使用“颜色”属性来对“图像”进行着色。请注意,这将以最可预测的方式影响最接近白色的图像部分。例如:
<Image File =“WhiteIcon.png”Color =“#f00”/>
这将使白色图标变红。
Debug –>按钮是可点击的控件,它们的外观和感觉从主题。
<App Theme =“Basic”>
<Button Text =“点击我!ux:Name =“button1”>
<Clicked>
<Set button1.Text =“Clicked!” />
</ Clicked>
</ Button>
</ App>
这个小例子将创建一个覆盖整个屏幕的“Button”。当您点击它时,其标签将从“点击我!到“点击!”。
在Fuse,几乎任何东西都可以很容易地做可点击(和tappable等)。因此,如果您想为按钮设计自定义的外观和感觉,可以使用任何组件:
<App>
<Rectangle Fill =“#309”>
<Clicked>
<DebugAction Message =“Rectangle got clicked”/>
</ Clicked>
</ Rectangle>
</ App>
当您单击矩形时,如果您在预览模式下运行,则“Message”输出将显示在Monitor中。它也将显示在标准设备日志中,或者,如果您从命令行启动预览过程,在标准控制台中。
事件触发器
“Button”也可以接受“Clicked”作为event-trigger:
<App Theme =“Basic”>
<JavaScript>
module.exports = {
buttonClick:function(args){console.log(“Button was clicked”); }}
}}
</ JavaScript>
<Button Text =“点击我!Clicked =“{buttonClick}”/>
</ App>
当你想从事件中驱动业务逻辑时,这是很方便的。
Switch
为了接受开/关式输入,Fuse有一个Switch
-control:
<开关/>
要使其对打开响应,您可以使用WhileTrue-trigger:
<App Theme =“Basic”>
<StackPanel>
<Switch>
<WhileTrue>
<Change rectangle.Width =“160”Duration =“0.5”
Easing =“CircularInOut”/>
</ WhileTrue>
</ Switch>
<Rectangle ux:Name =“rectangle”Width =“70”Height =“70”Fill =“#909”/>
</ StackPanel>
</ App>
要使它处于相反的状态,可以使用WhileFalse或WhileTrue Invert =“true”
。
如果你想要“开关”开始被激活:
<Switch Value =“true”/>
Switch
发出的事件也可以从JavaScript处理:
<App Theme =“Basic”>
<JavaScript>
module.exports = {
switchChanged:function(args){
console.log(“Switch value is:”+ args.value);
}}
};
</ JavaScript>
<StackPanel>
<Switch Value =“true”ValueChanged =“{switchChanged}”/>
</ StackPanel>
</ App>
###数据绑定开关
你也可以使用它的’Value属性来数据绑定
Switch`:
<App Theme =“Basic”>
<JavaScript>
var Observable = require(“FuseJS / Observable”);
var switchValue = Observable(false);
module.exports = {
switchValue:switchValue,
enableSwitch:function(){switchValue.value = true; },
disableSwitch:function(){switchValue.value = false; },
switchChanged:function(args){
console.log(“Switch value is:”+ args.value);
}}
};
</ JavaScript>
<StackPanel>
<Switch Value =“{switchValue}”ValueChanged =“{switchChanged}”/>
<Grid ColumnCount =“2”>
<Button Text =“Disable”Clicked =“{disableSwitch}”/>
<Button Text =“Enable”Clicked =“{enableSwitch}”/>
</ Grid>
</ StackPanel>
</ App>
滑块
要显示滑块:
<Slider />
要对正在移动的滑块作出反应,请使用ProgressAnimation
。考虑这个代码,它允许你从0到90度旋转Rectangle
:
<StackPanel>
<Slider>
<ProgressAnimation>
<Rotate Target =“rectangle”Degrees =“90”/>
</ ProgressAnimation>
</ Slider>
<Rectangle ux:Name =“rectangle”Width =“100”Height =“100”Fill =“#808”/>
</ StackPanel>
你也可以听’ValueChanged`事件:
<App Theme =“Basic”>
<JavaScript>
module.exports = {
sliderValueChanged:function(args)
{
console.log(“Value:”+ args.value);
}}
};
</ JavaScript>
<Slider ValueChanged =“{sliderValueChanged}”/>
</ App>
当将滑块从最左侧移动到最右侧时,控制台将输出0到100之间的浮点数,这是默认的“最小值”和“最大值”。这些属性也可以设置:
<滑块最小值=“4”最大值=“42”/>
###数据绑定滑块
也可以对滑块位置进行数据绑定:
<App Theme =“Basic”>
<JavaScript>
var Observable = require(“FuseJS / Observable”);
var sliderValue = Observable(42);
var sliderLabel = sliderValue.map(function(val){
return“当前位置:”+ val;
});
module.exports = {
sliderValue:sliderValue,
sliderLabel:sliderLabel
};
</ JavaScript>
<StackPanel>
<Slider Value =“{sliderValue}”/>
<Text TextAlignment =“Center”Value =“{sliderLabel}”/>
</ StackPanel>
</ App>
TextInput和TextEdit
保险丝提供两种不同的控制输入和编辑文本:
TextInput
是一个根据当前Theme装饰的文本编辑器。TextEdit
是没有视觉装饰的纯文本编辑器,否则等同于TextInput
。
在下面的例子中,TextInput
和TextEdit
可以互换使用:
<JavaScript>
var valueChanged = function(args){
console.log(args.value);
}}
module.exports = {
valueChanged:valueChanged
};
</ JavaScript>
<TextInput ValueChanged =“{valueChanged}”/>
你也可以轻松做双向数据绑定:
<App Theme =“Basic”>
<JavaScript>
var Observable = require(“FuseJS / Observable”);
var name = Observable(“”);
var greeting = name.map(function(name){
if(name ==“”){
return“输入你的名字”;
} else {
return“Hello there,”+ name +“!”;
}}
});
var clearName = function(){
name.value =“”;
}}
module.exports = {
name:name,
问候:问候,
clearName:clearName
};
</ JavaScript>
<StackPanel>
<StatusBarBackground />
<DockPanel>
<Text Dock =“Left”Alignment =“VerticalCenter”> Name:</ Text>
<TextInput Value =“{name}”Alignment =“VerticalCenter”/>
</ DockPanel>
<Text TextAlignment =“Center”Value =“{greeting}”/>
<Button Clicked =“{clearName}”Text =“Clear”/>
</ StackPanel>
</ App>
如果要接受密码,您可能需要屏蔽用户输入:
<TextInput IsPassword =“true”/>
如果你想接受数值主要,你可以设置一个InputHint
:
<TextInput InputHint =“Integer”/>
InputHint的有效值是
Default,
Email,
Integer,
Decimal,
Phone,
Url。这些被称为“提示”,因为他们可能不会做任何事情,这取决于你在哪个平台。例如,当在桌面上时,键盘将是相同的,无论是什么提示添加到
TextInput`。
TextInput
也允许您通过多行输入内容,而不是向右滚动,默认情况下:
<TextInput IsMultiline =“true”/>
您也可以选择完全停用编辑功能:
<TextInput IsReadOnly =“true”/>
当一个TextInput
获得焦点时,它通常会召唤设备的屏幕键盘。Fuse提供了许多机制来响应这个事件,其中一个是WhileKeyboardVisible
:
<文本值=“某种说明”>
<WhileKeyboardVisible>
<Move Y =“ - 1”RelativeTo =“Keyboard”/>
</ WhileKeyboardVisible>
</ Text>
<TextInput />
正如你可以看到,WhileKeyboardVisible
可以附加到一个任意的元素,你可以做任何你想要的,作为对屏幕键盘占用屏幕上的空间的响应。
只读的“RenderValue”属性给你实际上正在绘制的字符串。例如,如果IsPassword
为真,它将包含掩码密码(即••••••
)。
Styling TextInput
CaretColor
属性允许您更改插入符的颜色:
<TextInput CaretColor =“#ff0000”/>
如果你想改变选择的颜色,SelectionColor
使你能做到:
<TextInput SelectionColor =“#00ffaa”/>
如果希望在TextInput为空时显示某个默认字符串,可以添加占位符值
<TextInput PlaceholderText =“我的占位符文本”/>
它也可以有一个单独的颜色
<TextInput PlaceholderText =“我的占位符文本”PlaceholderColor =“#eee”/>
章节## ScrollView
保险丝有一个
ScrollView
,可以用于导航大于可用大小的内容。</ ScrollView>
为了限制
ScrollView
的行为,你可以设置ScrollDirection:</ ScrollView>
AllowedScrollDirections
的有效设置包括Horizontal
,Both
和Vertical
(默认)。
ScrollingAnimation
可以基于绝对ScrollView
位置来动画属性。例如,让我们删除一个顶部窗口,一个ScrollView
向下滚动:
<App Theme =“Basic”Background =“#fff”>
<Panel >
<Panel 对齐=“顶部”高度=“50”ux:名称=“ledge”>
<Text Alignment =“Center”TextAlignment =“Center”TextColor =“#fff”Value =“TopLedge”/>
<Rectangle Fill =“#000”/>
</ Panel>
<ScrollView>
<ScrollingAnimation From =“0”To =“50”>
<Change ledge.Opacity =“0”/>
</ ScrollingAnimation>
<StackPanel>
<!-- 阻止在scrollview中的顶部 -->
<Panel 高度=“50”/>
<!-- ... Content ... -->
</ StackPanel>
</ ScrollView>
</ Panel>
</ App>
NativeViewHost
某些视图仅作为本机组件可用。这些显然是与本机主题的开箱即用,但我们如何可以将它们与基于GraphicsTheme
的应用程序中的自定义组件一起使用?通过合成它们与NativeViewHost!例如,这里是一个WebView添加了NativeViewHost:
|
请注意,在NativeViewHost中添加的视图总是呈现在您的其他Graphics主题内容的in front,因此您使用深度和渲染顺序需要考虑这一点。(例如:像<BringToFront>
和`
要实现相反的目的,在Native主题中添加自定义组件和视图,请继续阅读。
GraphicsView
GraphicsView
是NativeViewHost的对应部分,并允许您使用Native主题向App添加Fuse视图。
|
和NativeViewHost一样,注意当混合Native和Fuse视图时,深度排序会有不同的行为。
WebView
包括Web内容Fuse为Android和iOS提供了一个本地WebView组件。WebView只是本地的,因此需要包含在NativeViewHost中,如果您希望使用它与图形主题。
WebView可以用于通过http协议或通过加载HTML作为字符串来呈现Web内容,并且钩住一些有用的触发器来构建定制的浏览体验,例如PageBeginLoading,WhilePageLoading和PageLoaded 。导航触发器像GoBack和GoForward与WebView特定的,如重新加载,LoadUrl和LoadHtml的补充。它也可以用于馈送ProgressAnimation。
EvaluateJS触发器是值得注意的,因为它允许在WebView的上下文中运行任意的JavaScript,并将结果数据反馈到Fuse中:
|
WebView还可以通过包装HTML节点或通过LoadHtml触发器操作来提供原始HTML以显示:
<LoadHtml TargetNode =“myWebView”BaseUrl =“http://my.domain”Source =“{html}”/>
JavaScript API
WebView的某些方法通过JavaScript公开
goto(“http://myurl.com”)
loadHtml(“my html string”)
loadHtml(“my html string”,“http://my.baseurl.com”)
setBaseUrl(“http://my.baseurl.com”)
HTML
<HTML />
是一个语义实用程序节点,用于使用原始HTML来提供WebView组件或LoadHtml操作:
|
MapView
MapView
允许您使用平台本地的映射API,在Android上使用Google地图和在iOS上使用苹果地图,向用户展示带注释,互动的全球范围的地图。
MapView
是一个本地控件,因此需要包含在一个NativeViewHost中以与Graphics主题一起显示。与其他本地移动控件一样,目前没有`MapView’可用于桌面目标。
获取一个MapView
包含在你的应用程序是简单的:简单地包括节点在你的UX中,你通常将与本机控件:
|
要初始化和操作地图摄像机,请使用“纬度”,“经度”,“缩放”,“倾斜”和“轴承”属性,所有这些都是双向绑定。Zoom
采用平台特定范围内的值,iOS上的米高于地面,Android上为“缩放因子”。
通过使用“Style”属性和“MapStyle”枚举设置渲染样式,可以进一步自定义地图。选项是“Normal”,“Satellite”和“Hybrid”。
Android上的地图
Google地图需要以下内容:
一旦你有你的密钥,它必须添加到你的项目文件,如下所示:
|
JavaScript API
MapView的某些方法通过JavaScript公开。
setMarkers([{latitude:0,longitude:0,label:“Zero”}])
setLocation(latitude,longitude)
setTilt(0.0)
setZoom(1.0)
setBearing(0.0)
MapMarker
要注释地图,您必须使用“MapMarker”节点来装饰它。MapMarker
节点是包含“纬度”,“经度”和“标签”的简单值对象
|
如果你需要从JS动态生成MapMarkers,数据绑定和每个都是你的朋友。在我们编写脚本时,我们可能会勾选“MarkerTapped”事件来检测用户何时选择了标记。
|
Element
这里有一些常见的所有Element
类型的属性:
HitTestMode
当与元素交互时,有时期望能够区分哪些元素可以与其交互以及如何进行交互。这通常被称为“命中测试”。在Fuse中,元素如何与用户输入交互可以使用HitTestMode
设置。
考虑这个代码:
<Grid ColumnCount =“2”>
<Rectangle Width =“100”Height =“100”Fill =“#808”>
<Clicked>
<DebugAction Message =“点击左侧”/>
</ Clicked>
</ Rectangle>
<Rectangle Width =“100”Height =“100”Fill =“#808”HitTestMode =“None”>
<Clicked>
<DebugAction Message =“点击右键”/>
</ Clicked>
</ Rectangle>
</ Grid>
它将布局两个Rectangle
s并将Clicked
触发器添加到它们。但是,当点击时,只有左边的一个会输出任何内容,因为在右边的矩形上显式地禁用了命中测试。如果你有视觉元素遮挡下面的元素,你想让下面的元素响应输入,这可能是非常有帮助的。
HitTestMode
的有效值为:
- HitTestMode.None:None - 这个元素不会做命中测试
- HitTestMode.LocalBounds:LocalBounds - 这个元素将根据其大小进行命中测试
- HitTestMode.LocalVisual:LocalVisual - 这个元素将根据其外观进行命中测试
- HitTestMode.LocalBoundsAndChildren:LocalBoundsAndChildren - 点击测试将包括元素及其子元素的边界
- HitTestMode.LocalVisualAndChildren:LocalVisualAndChildren - 命中测试将包括元素及其子元素的外观
ClipToBounds
通常,当将一个元素布置在另一个元素内部时,内部元素可以自由地居住在父元素之外:
<Panel 宽度=“100”高度=“100”>
<Image Margin =“ - 100”File =“Pictures / Picture1.jpg”
StretchMode =“UniformToFill”/>
</ Panel>
这个“图像”将显示为300pt宽和高,因为“Panel ”不会将孩子剪裁到其边界。
如果你打算把Image
剪辑修改为它的父大小,只需在Panel
中添加ClipToBounds即可:
<Panel 宽度=“100”高度=“100”ClipToBounds =“true”>
<Image Margin =“ - 100”File =“Pictures / Picture1.jpg”
StretchMode =“UniformToFill”/>
</ Panel>
现在,Image
不会溢出Panel
的边界。
Opacity
你可以使用Opacity
属性设置对象的透明度。
<Panel 不透明度=“0.5” />
当“Opacity”设置为0.0时,元素是完全透明的,但仍会响应hit tests。当“Opacity”设置为1.0时,元素将处于其默认状态。
Layer
而不是分开布局,元素可以通过使用Layer
属性作为父母的背景或叠加。
在以下示例中,按钮的文本将显示在矩形上方。
|
Layer
的有效值为:
Layout
(默认) - 元素在布局中像往常一样,在“Background”和“Overlay”之间绘制Background
- 元素是在* Layout`层后面绘制的,并不影响布局Overlay
- 元素在 Layout`层的顶部绘制,并不影响布局
ZOffset
通常,元素按照在UX中显示的顺序绘制。
你可以通过使用ZOffset
属性(默认为0)来影响这个排序。
具有较高“ZOffset”值的元素绘制在具有较低值的那些值之上。然而,他们仍然在他们的层。
在下面的示例中,蓝色矩形将出现在红色矩形的上方,即使它们的顺序告诉我们。
|
- 注意:*儿童的Z顺序完全独立于3D中的Z轴。元素仍然可以转换为任何Z轴位置,旋转到Z维度,或具有实际深度,而与其子Z轴顺序无关。
关于控制:控制
在Fuse中,我们使用control来描述一个具有语义功能的UI组件,但在视觉外观上可能有很大的变化。
例如,Button定义了某些属性和事件,例如Clicked,但不同的themes或styles之间的按钮外观和感觉可能会有很大的不同。
效果
保险丝具有渲染一组可以添加到大多数控件的视觉效果的能力。重要的是要理解,为了使这些工作,你需要在图形模式; 原生主题在它们呈现这些效果的能力方面受到限制。
DropShadow
向元素添加DropShadow
:
<Rectangle Width =“50”Height =“50”Fill =“#808”>
<DropShadow />
</ Rectangle>
从一个软的“DropShadow”从上到下:
<Rectangle Width =“50”Height =“50”Fill =“#808”>
<DropShadow Angle =“90”Distance =“12”Size =“20”Spread =“0.1”/>
</ Rectangle>
它也可以用于创造艺术效果,如外部发光:
<Panel Background =“#000”>
<Circle Width =“50”Height =“50”Fill =“#808”>
<DropShadow Distance =“0”Size =“50”Spread =“0.2”Color =“#ff06”/>
</ Circle>
</ Panel>
DropShadow
有以下属性:
- `角度’ - 光从哪个方向来:
- 0 - 右
- 90 - 顶
- 180 - 左
- 270 - 底
- `距离’ - 从阴影源的点的距离
Size
- 阴影的大小Spread
- 阴影如何掉落。越接近0,线性越多。保持这个值低(实验低于1.0),否则你会得到工件- `颜色’ - dropshadow应该有哪种颜色。注意,这也支持Alpha通道调整阴影透明度(使用十六进制颜色值的第四个数字声明,例如#FFF0到#FFFF)。
Blur
模糊元素:
<Text Value =“Hello there!”>
<Blur Radius =“0.9”/>
</ Text>
注意,虽然’Blur’的`Radius’可以像大多数其他属性一样动画,这可能是一个昂贵的操作,并且应该在设备上测试,以确保它的行为正确。
Desaturate
为了“去饱和”一个元素,完全或部分:
<Image File =“Pictures / Picture1.jpg”>
<去饱和量=“0.4”/>
</ Image>
1.0的量将完全“去饱和”元素。
半色调
添加经典半色调效果:
<Image File =“Pictures / Picture1.jpg”>
<半色调/>
</ Image>
Halftone
接受:
Spacing
- 点之间的距离(float
,默认为0.5)平滑度' - 点边缘的硬或软的程度(
float`,默认为2)Intensity
- 应用了多少效果(float
,默认为1)DotTint
- 点的色调量(float
,默认0.5)PaperTint
- 纸张的色泽量(float
,默认值0.2)
Mask
保险丝允许你用一个图像或ImageSource
来屏蔽一个元素。
<Rectangle Width =“50”Height =“50”>
<Mask File =“Masks / Flower.png”/>
</ Rectangle>
“Mask”效果接受以下属性:
Mode
- 如何解释掩码源RGBA
(默认) - 使用源图像的Alpha通道作为掩码,并将掩码中的RGB值与要屏蔽的元素的RGB值相乘- “Alpha” - 使用源图像的Alpha通道,而不接触来自遮罩元素的RGB值
- “灰度” - 使用灰度掩码的颜色分量作为与原始Alpha值的乘法因子
File
- 如果你有一个图片捆绑作为项目的一部分Source
- 如果你有另一个来源Image
,例如HttpImageSource
如果您使用带有alpha通道的白色图像,“RGBA”和“Alpha”将具有相同的结果。
掩码将总是伸展自身以匹配要掩蔽的元素的大小。