Introduction to Views
出自OpenFace
第六章 视图介绍
第二部分 教程介绍
介绍
视图是OpenLaszlo应用程序中基本的可视化元素。它可以指定元素间怎么样交互。
注:这里说的视图指所有能在界面上显示的标签(广义),view、text、drawview等均是视图,为了便于描述,以下文档中说的视图是指广义的,而使用view表示一个具体的view标签(或者说狭义的视图)。
Example 6.1.
<canvas height="300" width="500">
<simplelayout axis="y" spacing="10"/>
<text>Here is some text.</text>
<text>I could ramble for hours.</text>
</canvas>
约束和修改
约束是使视图属性保持某个值的对象。约束的种类,有可能是”某文本的Y值”或”父视图的宽度”或其他。下面这个例子中设置了一个基于父视图宽度的约束。
Example 6.2. Constraining text position
<canvas height="300" width="500">
<simplelayout axis="y" spacing="10"/>
<text>Here is some text.</text>
<text>I could ramble for hours.</text>
<text x="${parent.width/2}" >
My Text!
</text>
</canvas>
我们这里说的是“将按钮的x坐标限制在他的父视图的一半的位置”。在这个case中parent是指canvas所表示的区域(从界面上看就是整个白色区域)
这里的修改(modifier)是一种“一分为二”的操作。
我们想让最后一个view总是在窗口的中央显示,而不管view的宽度是否改变。
我们可以这样做:
Example 6.3
<canvas height="300" width="500">
<simplelayout axis="y" spacing="10"/>
<text>Here is some text.</text>
<text>I could ramble for hours.</text>
<view x="${(parent.width/2)-(this.width/2)}" height="20" bgcolor="red" width="20" >
</view>
</canvas>
这样无论这个view的长度怎么变化,它都居中显示。为了证明这点,我们添加一段script让这个view长度发生变化。
这里您暂时不需要理解它是如何工作的,只须要观察当您按键时这个view时宽度的变化,我们会在“脚本”这部分再介绍它。
Example 6.4. Growing view
<canvas height="300" width="300">
<simplelayout axis="y" spacing="10"/>
<text>Here is some text.</text>
<text>I could ramble for hours.</text>
<text text="Press any key to change view's width!" x="50" />
<view x="${(parent.width/2)-(this.width/2)}" width="30" height="30"
bgcolor="red" oninit="LzFocus.setFocus(this)">
<handler name="onkeydown" reference="LzKeys">
this.setAttribute('width', parseFloat(this.getAttribute("width"))+10);
</handler>
</view>
</canvas>
在上面的例子中我们使用了两种引用一个view的属性的方法,比如说使用“this.getAttribute('width')” 和 “this.width”。
这两种方式是有区别的,并且在不同的环境下决定了您是否可以使用“this.width”语法。在这个约束中,您只能使用“this.width”。
布局器和容器视图
怎么在canvas中产生一排自上而下的文本?我们可以试着在上面添加一些如下的文本:
Example 6.5. Vertically aligned texts
<canvas height="300" width="500">
<simplelayout axis="y" spacing="10"/>
<text>1</text>
<text>2</text>
<text>3</text>
<text>Here is some text.</text>
<text>I could ramble for hours.</text>
<view x="${(parent.width/2)-(this.width/2)}" width="30" height="30"
bgcolor="green"oninit="LzFocus.setFocus(this)">
<handler name="onkeydown" reference="LzKeys">
this.setAttribute('width',parseFloat(this.getAttribute('width'))+10);
</handler>
</view>
</canvas>
我们不能更改<simplelayout>标签,否则会导致这个view中其它元素排版混乱。但是我们可以将这三个文本放在另外一个独立的view中,然后这个新的view作为一个独立的整体在原来的view中。
Example 6.6
<canvas height="300" width="500">
<simplelayout axis="y" spacing="10"/>
<view bgcolor="#663311">
<simplelayout axis="x" spacing="2"/>
<text>1</text>
<text>2</text>
<text>3</text>
</view>
<text>Here is some text.</text>
<text>I could ramble for hours.</text>
<view x="${(parent.width/2)-(this.width/2)}" width="30" height="30" bgcolor="green"
oninit="LzFocus.setFocus(this)">
<handler name="onkeydown" reference="LzKeys">
this.setAttribute('width',parseFloat(this.getAttribute('width'))+10);
</handler>
</view>
</canvas>
通过设置bgcolor属性我们能够看见一个view的大小,只要足够大就可以了。如果没有指定它的高度和宽度,它将根据它里面的元素确定自己的大小。
如果我们要让view像工具栏那样在窗口的顶部排成一行(从左到右,颜色一致)呢?
我们将使红色视图的宽度约束为它的父视图的宽度。
Example 6.7 Constraining a width to parent's width
<canvas height="300" width="500">
<simplelayout axis="y" spacing="10"/>
<view bgcolor="#ff0000"
width="${parent.width}">
<simplelayout axis="x" spacing="5"/>
<view width="20" height="10" bgcolor="green"/>
<view width="20" height="10" bgcolor="green"/>
<view width="20" height="10" bgcolor="green"/>
</view>
<text>Here is some text.</text>
<text>I could ramble for hours.</text>
<text x="${(parent.width/2)-(this.width/2)}"
oninit="this.setAttribute('width', this.getAttribute('width')+10);">
My text
</text >
</canvas>
现在,我们把视图延长到窗口宽度了。类似的还可以把视图约束到它的子元素上。
Example 6.8 Constraining view to child's height
<canvas height="300" width="500">
<simplelayout axis="y" spacing="10"/>
<view bgcolor="#ff0000" width="${parent.width}" height="${this.myview.height+8}">
<simplelayout axis="x" spacing="5"/>
<view width="20" height="10" bgcolor="green" name="myview"/>
<view width="20" height="10" bgcolor="green"/>
<view width="20" height="10" bgcolor="green"/>
</view>
<text>Here is some text.</text>
<text>I could ramble for hours.</text>
<text x="${(parent.width/2)-(this.width/2)}" oninit="LzFocus.setFocus(this)">
<handler name="onkeydown" reference="LzKeys">
this.setAttribute('width',parseFloat(this.getAttribute('width'))+10);
</handler>
My text
</text>
</canvas>
为了能引用一个具体的元素对象,需要给这个元素设置一个name属性。
之前介绍过有个属性可以将内容排放在中间部分。现在就来使用它。
Example 6.9 Using the 'valign' attribute
<canvas height="300" width="500">
<simplelayout axis="y" spacing="10"/>
<view bgcolor="#ff0000" width="${parent.width}" height="${this.refButton.height+8}">
<simplelayout axis="x" spacing="5"/>
<text name="refButton" valign="middle">
1
</text>
<text>2</text>
<text>3</text>
</view>
<text>Here is some text.</text>
<text>I could ramble for hours.</text>
<text x="${(parent.width/2)-(this.width/2)}" oninit="LzFocus.setFocus(this)">
<handler name="onkeydown" reference="LzKeys">
this.setAttribute('width',parseFloat(this.getAttribute('width'))+10);
</handler>
My text
</text>
</canvas>
属性valign将视图按其父视图的高度放在中部。该属性可以取顶部、中间和底部三个值。还有一个属性align可以按水平方向排列视图。这样做的问题是我们必须给每个text一个align属性。
将视图内所有的text封装起来就可以解决这个问题。之后我们只对他们使用一次valign属性就ok了。
Example 6.10 Applying 'valign' to container view
<canvas height="300" width="500">
<simplelayout axis="y" spacing="10"/>
<view bgcolor="#ff0000" width="${parent.width}" height="${this.buttons.refButton.height+8}">
<simplelayout axis="x" spacing="5"/>
<view name="buttons" valign="middle">
<text name="refButton">1</text >
<text >2</text >
<text >3</text >
</view>
</view>
<text>Here is some text.</text>
<text>I could ramble for hours.</text>
<text x="${(parent.width/2)-(this.width/2)}" oninit="LzFocus.setFocus(this)">
<handler name="onkeydown" reference="LzKeys">
this.setAttribute('width',parseFloat(this.getAttribute('width'))+10);
</handler>
My text
</text>
</canvas>
我们似乎失去了text 1和 text 2 ,我们可以回复原貌。您可能注意到了我们为新视图命名为"buttons"。我们也要将访问text 的高度的方式从this.refButton.height改变this.buttons.refButton.height.只是必要的,因为refbutton现在在红色视图内部的texts中。
现在可以恢复text 1和2 了。在视图"buttons"中没有什么需要在应用运行时把它们隔开。因为我们忘记把<simplelayout>标签转成视图buttons了。
Example 6.11 Using <simplelayout> to align texts
<simplelayout axis="y" spacing="10"/>
<view bgcolor="#ff0000" width="${parent.width}" height="${this.buttons.refButton.height+8}">
<simplelayout axis="x" spacing="5"/>
<view name="buttons" valign="middle">
<simplelayout axis="x" spacing="5" />
<text name="refButton">1</text >
<text >2</text >
<text >3</text >
</view>
</view>
<text>Here is some text.</text>
<text>I could ramble for hours.</text>
<text x="${(parent.width/2)-(this.width/2)}" oninit="LzFocus.setFocus(this)">
<handler name="onkeydown" reference="LzKeys">
this.setAttribute('width',parseFloat(this.getAttribute('width'))+10);
</handler>
My text
</text>
为了让视图看起来更好我们可以改变它的颜色。

