在本文中,将探讨如何在PlayBook设备上使用BlackBerry Tablet OS SDK中的QNX UI组件库来开发应用程序。将通过一些代码示例来展示如何实现这一点。
首先,将创建一个基于MXML的应用程序,使用一个名为QApplication的新类,该类扩展了QNX Container,然后包含一个QNX UI Button。以下是实现这一功能的代码示例:
<?xml version="1.0" encoding="utf-8"?>
<r:QApplication xmlns:r="http://ns.renaun.com/mxml/2010" xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:buttons="qnx.ui.buttons.*">
<buttons:Button />
</r:QApplication>
在ActionScript中实现相同的功能,代码如下:
package {
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import qnx.ui.buttons.Button;
import qnx.ui.core.Container;
public class DisplayButtonAS3 extends Sprite {
public function DisplayButtonAS3() {
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
var container:Container = new Container();
var but:Button = new Button();
container.addChild(but);
addChild(container);
container.setSize(stage.stageWidth, stage.stageHeight);
}
}
}
通过这种方式,可以完全使用MXML创建PlayBook应用程序,而不需要Flex。此外,还可以使用Flex 4(包括最新的SDK,支持移动设备)并混合使用一些QNX UI组件。所需要做的就是向项目/应用程序中添加QMXML.swc(针对Tablet OS SDK 0.9.2编译)和命名空间xmlns:r="http://ns.renaun.com/mxml/2010"。
这听起来非常令人兴奋!然而,它仍然是另一个UI库。所以,QNX UI组件库并不会突然像Flex Spark架构那样工作。不,QNX UI库走自己的路,使用时需要记住这一点。这并不意味着它不好,只是要意识到它与Flex不同。
如果想继续尝试示例,请确保从BlackBerry开发者网站获取BlackBerry Tablet OS SDK:
注意:本文撰写时,使用的是BlackBerry Tablet OS SDK 0.9.1。
好的,明白了,让看看一些代码!首先!所有代码都可以在GitHub上找到,去获取它。仓库中有一些Flash Builder项目。主要的库项目称为QMXML。创建自己的项目所需的QMXML.swc(针对Tablet OS SDK 0.9.2编译)可以在bin文件夹中找到,或者可以从这里下载:
其他项目是示例项目,称为NonFlexMXMLUsingQNX和FlexAndQNX。NonFlexMXMLUsingQNX项目包含了上面显示的DisplayButton应用程序,以及另一个项目,展示了一些使用QNX流/包含属性的QNX UI类嵌套在容器中。
FlexAndQNX应用程序是一个标准的Flex 4 spark(非移动)应用程序,它使用了QNX Button和List以及Flex LineSeries数据图表。这在QNX UI库目前缺乏图表功能的情况下是有意义的。以下是应用程序在模拟器中运行的视图:
FlexAndQNX在模拟器中
以下是FlexAndQNX应用程序的源代码,允许直接在Flex中混合QNX UI组件:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:r="http://ns.renaun.com/mxml/2010" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:buttons="qnx.ui.buttons.*" xmlns:listClasses="qnx.ui.listClasses.*" width="1024" height="600" backgroundColor="0xcccccc">
<s:layout>
<s:HorizontalLayout />
</s:layout>
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import qnx.ui.core.ContainerFlow;
import qnx.ui.core.SizeUnit;
import qnx.ui.data.DataProvider;
import qnx.ui.events.ListEvent;
private var data:Array = [];
[Bindable] private var chartData:ArrayCollection;
private function createData():void {
data = [];
for (var i:int = 0; i <50; i++) data.push({label: "Point " + i, data: i+(Math.random()*30), data2: i+60+(Math.random()*60), data3: i+80+(Math.random()*120)});
lstData.dataProvider = new DataProvider(data);
chartData = new ArrayCollection(data);
}
protected function lstData_listItemClickedHandler(event:ListEvent):void {
trace(event.data.data + " - " + event.row);
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Define custom colors for use as fills in the AreaChart control. -->
<mx:SolidColor id="sc1" color="0x336699" alpha=".3" />
<mx:SolidColor id="sc2" color="0x993333" alpha=".3" />
<mx:SolidColor id="sc3" color="0x339933" alpha=".3" />
<mx:SolidColorStroke id="s1" color="0x336699" weight="2" />
<mx:SolidColorStroke id="s2" color="0x993333" weight="2" />
<mx:SolidColorStroke id="s3" color="0x339933" weight="2" />
<mx:SeriesInterpolate id="seriesInterpolate" duration="500" />
</fx:Declarations>
<s:Group height="100%" width="20%">
<r:QContainer id="c" align="near">
<buttons:LabelButton label="Create Data" click="createData()" />
<listClasses:List id="lstData" size="100" sizeUnit="percent" listItemClicked="lstData_listItemClickedHandler(event)" />
</r:QContainer>
</s:Group>
<s:HGroup width="80%" height="100%">
<mx:AreaChart id="Areachart" height="100%" width="80%" paddingLeft="5" paddingRight="5" showDataTips="true" dataProvider="{chartData}">
<mx:horizontalAxis>
<mx:CategoryAxis categoryField="label" />
</mx:horizontalAxis>
<mx:series>
<mx:AreaSeries yField="data" form="curve" displayName="Plot 1" showDataEffect="{seriesInterpolate}" areaStroke="{s1}" areaFill="{sc1}" />
<mx:AreaSeries yField="data2" form="curve" displayName="Plot 2" showDataEffect="{seriesInterpolate}" areaStroke="{s2}" areaFill="{sc2}" />
<mx:AreaSeries yField="data3" form="curve" displayName="Plot 3" showDataEffect="{seriesInterpolate}" areaStroke="{s3}" areaFill="{sc3}" />
</mx:series>
</mx:AreaChart>
<mx:Legend dataProvider="{Areachart}" />
</s:HGroup>
</s:Application>
可能还有更多的QContainer类集成工作可以做,以使其更好地与Flex一起工作,但目前请遵循这些宽松的规则。当在Flex应用程序中混合QNX UI组件时,请始终以QContainer开始,将其视为小型QNX应用程序空间。将希望将其包装在Flex Spark Group或SkinnableContainer中,以QContainer填充其父级的全部宽度和高度。QContainer侦听其父级的RESIZE事件,然后使布局失效。然后根据其父级的新宽度和高度,重新测量自身及其子级。对于设置不同的QNX属性,如size和sizeUnit,还有一些余地,但最安全的做法是开始:
<s:Group height="100%" width="20%">
<r:QContainer />
</s:Group>
Group的任何尺寸变化都将自动被QContainer检测到,并且它将填充其父级的全部空间。
注意:BlackBerry Tablet OS SDK不提供其类的清单文件和命名空间,这意味着应用程序将有很多看起来像qnx.ui.buttons.*的命名空间。此外,一些QNX类可能会引起Flex的SystemManager控制舞台的问题,请告诉如果遇到某些问题。
项目类型、SDK和插件:Flash Builder 4和Flash Builder Burrito中有各种项目类型。此外,BlackBerry Tablet OS SDK为两个Flash Builder版本安装了插件。通常,所需要做的就是创建一个AIR项目并修改应用程序描述文件以用于移动设备(通常意味着非WindowedApplication并设置visible=true)。QMXML类将在Flex 4 spark桌面应用程序以及更新的Flex Hero移动应用程序和主题中工作。这假设项目已创建并指向BlackBerry Tablet OS SDK 0.9.1。
请注意,这些类经过了有限的测试,并希望能够试用它们。玩得开心!
旅程中的极客小贴士:使用MXML,将获得绑定。这是MXML的一大好处。但这也意味着不得不对一个没有考虑这一点的UI框架进行调整,使其能够工作。一些QNX UI框架的选择使这并不那么简单。不得不在可能会改变布局的属性中添加了很多钩子,并创建了布局失效/刷新。幸运的是,Container类是QNX UI库中唯一的Container,它只有半打与布局相关的属性。这使得这个解决方案变得可行。