BaseUI中文使用说明和范例

在Flex中,界面中的各个组件可以随着浏览器的大小而重新排列位置,始终在浏览器中保持满屏显示的状态。我们将这种效果称为“布局”。

Flex框架实现了一套自己的布局框架。在Flex3中,可以使用HBox、VBox等进行布局管理;在Flex4中,可以使用spark.layouts包中的布局管理器,这个包的布局功能更加强大和灵活

那么,在Flash或者纯AS项目中,如何实现布局呢?

侦听舞台的Resize事件是解决这个问题的常用方法。但是如果布局比较复杂,就需要大量的代码来实现这些布局,使用侦听Resize事件的方法未免显得繁琐。于是,就有人实现了AS下的布局类或者布局框架。例如:senocular Layout classYahoo ASTRA Layout Utility等等。本文介绍的是BaseUI

BaseUI的中文资料较少,这一篇官方说明的译文,通过它大致可以了解BaseUI的工作方式和特点。本文则准备以实例的方式基于一个纯AS项目来介绍BaseUI的基本用法,这样更容易理解。

一、BaseUI基本使用

在下面的这段代码中,建立了一个BaseUI的实例,然后绘制了一个shape并加入到显示列表中,将其置于舞台右下角,与舞台边框间隔10像素。

几个注意点:

  1. 必须设定stage的scaleMode为NO_SCALE,以及设定align为TOP_LEFT,否则布局可能会不正常;
  2. BaseUI必须基于stage,虽然基于root也能工作,但是可能会导致布局不正常;
  3. 将元素加入BaseUI并不等于加入显示列表,因此还需要将元素自行加入显示列表中

效果(在浏览器中查看swf或下载后使用Flash Player播放):

1 文件

源码:

 1[SWF(width=500,height=300,backgroundColor=0xcccccc)]
 2public class BaseUITest extends Sprite
 3{
 4    public function BaseUITest()
 5    {
 6        //绘制一个背景颜色以便于观察
 7        graphics.beginFill(0xFFFFFF);
 8        graphics.drawRect(0, 0, 500, 300);
 9        graphics.endFill();
10        //必须设置scaleMode和align,否则在布局的时候会不正常
11        stage.scaleMode = StageScaleMode.NO_SCALE;
12        stage.align = StageAlign.TOP_LEFT;
13        
14        //绘制一个背景颜色以便于观察
15        graphics.beginFill(0xFFFFFF);
16        graphics.drawRect(0, 0, 500, 300);
17        graphics.endFill();
18        //必须设置scaleMode和align,否则在布局的时候会不正常
19        stage.scaleMode = StageScaleMode.NO_SCALE;
20        stage.align = StageAlign.TOP_LEFT;
21        
22        //基于stage建立一个布局
23        _baseUI = new BaseUI(this.stage);
24        //为布局添加一个布局元素
25        var __elementRB:ElementUI = _baseUI.add(createShape(this.stage));
26        //设置该布局元素距右边和下方各10像素,并刷新布局使其生效
27        __elementRB.right = 10;
28        __elementRB.bottom = 10;
29        __elementRB.refresh();
30    }
31    
32    private var _baseUI:BaseUI;
33
34    //快速绘制一个Shape用于测试,如果绘制的时候提供了父显示对象,就将其加入父显示对象的显示列表
35    private function createShape($parent:DisplayObjectContainer=null):Shape
36    {
37        var __shape:Shape = new Shape();
38        __shape.graphics.lineStyle(2, 0xFF0000);
39        __shape.graphics.drawRect(0, 0 , 30, 30);
40        if($parent)
41            $parent.addChild(__shape);
42        return __shape;
43    }
44}

二、可以使用几个BaseUI?

最开始,我以为BaseUI是可以用于其它的显示容器的,于是就做了个实验,建立一个Sprite并加入到stage中,并基于这个Sprite建立一个BaseUI,再使用这个新的BaseUI来控制Sprite的子显示对象。但发现这样做出来的布局无法正常显示。当然,可能是由于我遗忘了某些东西或者使用方法不正确,但我还是建议对于子容器使用com.soma.ui.layouts包。

三、HBoxUI的用法

HBox是一个横向布局容器,它继承自LayoutUI,而LayoutUI则继承自MovieClip(为什么是MovieClip而不是Sprite?这个我也不知道,我在源码中将LayoutUI的超类改为了Sprite,使用也一切正常)。

下面这段代码中建立了一个HBox容器,并为它增加了6个子显示对象,通过对HBox属性的设定,可以控制子显示对象的间隔以及在HBox中的对其方式。

几个注意点:

  1. backgroundAlpha属性默认是完全透明,因此如果要显示背景色,就必须将其设定为大于0的值;
  2. 因为LayoutUI是显示对象,因此可以直接将HBoxUI的实例加入显示列表,而ElementUI是不能加入显示列表的;
  3. 要获取LayoutUI的对应ElementUI,可以使用element属性;
  4. 不需要将LayoutUI加入到BaseUI的实例中,但需要为LayouUI传递stage,如果传递其它的容器,则可能会导致布局问题。

效果(在浏览器中查看swf或下载后使用Flash Player播放):

1 文件

源码:

 1//增加一个HBox容器,设定背景色和透明度
 2var __hbox:HBoxUI = new HBoxUI(this.stage);
 3__hbox.backgroundColor = 0x0000FF;
 4//透明度默认是完全透明,所以必须设定才能让背景色显示出来
 5__hbox.backgroundAlpha = 0.2;
 6//让该容器置顶,宽度始终与舞台相同
 7__hbox.right = 0;
 8__hbox.left = 0;
 9__hbox.top = 0;
10//让容器中的子显示对象的横向间隔为10像素
11__hbox.childrenGap = new GapUI(10);
12//让容器中的子显示对象基于容器的右下方对齐
13__hbox.childrenAlign = HBoxUI.ALIGN_BOTTOM_RIGHT;
14//加入6个shape
15for(var i:int=0; i<6; i++)
16{
17    createShape(__hbox);
18}
19//将容器加入显示列表并刷新容器布局
20addChild(__hbox);
21__hbox.refresh();

四、CanvasUI的用法

使用HBoxUI和VBoxUI可以实现横向和纵向的布局。但我们有时候需要布局更灵活一些。例如希望3个显示对象分别排列在容器的左、中、右,如何处理呢?

下面这段代码建立了一个CanvasUI容器,在容器中增加了3个shape,并实现左、中、右排列。

效果(在浏览器中查看swf或下载后使用Flash Player播放):

1 文件

源码:

 1//增加一个CanvasUI容器
 2var __canvas:CanvasUI = new CanvasUI(this.stage);
 3__canvas.backgroundColor = 0xFF0000;
 4__canvas.backgroundAlpha = .5;
 5//让canvas在舞台中纵向居中,宽度与舞台宽度始终相同
 6__canvas.verticalCenter = 0;
 7__canvas.left = 0;
 8__canvas.right = 0;
 9//建立canvas的第1个子显示对象,在canvas中左下对齐
10var __shape1:Shape = createShape();
11var __element1:ElementUI = __canvas.add(__shape1);
12__element1.left = 0;
13__element1.bottom = 0;
14//建立canvas的第2个子显示对象,在canvas中居中对齐
15var __shape2:Shape = createShape();
16var __element2:ElementUI = __canvas.add(__shape2);
17__element2.horizontalCenter = 0;
18__element2.verticalCenter = 0;
19//建立canvas的第3个子显示对象,在canvas中右上对齐
20var __shape3:Shape = createShape();
21var __element3:ElementUI = __canvas.add(__shape3);
22__element3.right =0;
23addChild(__canvas);
24__canvas.refresh();

五、全部源代码

  1package
  2{
  3import com.soma.ui.BaseUI;
  4import com.soma.ui.ElementUI;
  5import com.soma.ui.layouts.CanvasUI;
  6import com.soma.ui.layouts.HBoxUI;
  7import com.soma.ui.vo.GapUI;
  8
  9import flash.display.DisplayObjectContainer;
 10import flash.display.Shape;
 11import flash.display.Sprite;
 12import flash.display.StageAlign;
 13import flash.display.StageScaleMode;
 14import flash.events.Event;
 15
 16[SWF(width=500,height=300,backgroundColor=0xcccccc)]
 17public class BaseUITest extends Sprite
 18{
 19    public function BaseUITest()
 20    {
 21        //绘制一个背景颜色以便于观察
 22        graphics.beginFill(0xFFFFFF);
 23        graphics.drawRect(0, 0, 500, 300);
 24        graphics.endFill();
 25        //必须设置scaleMode和align,否则在布局的时候会不正常
 26        stage.scaleMode = StageScaleMode.NO_SCALE;
 27        stage.align = StageAlign.TOP_LEFT;
 28        
 29        //基于stage建立一个布局
 30        _baseUI = new BaseUI(this.stage);
 31        //为布局添加一个布局元素
 32        var __elementRB:ElementUI = _baseUI.add(createShape(this.stage));
 33        //设置该布局元素距右边和下方各10像素,并刷新布局使其生效
 34        __elementRB.right = 10;
 35        __elementRB.bottom = 10;
 36        __elementRB.refresh();
 37        
 38        //增加一个HBox容器,设定背景色和透明度
 39        var __hbox:HBoxUI = new HBoxUI(this.stage);
 40        __hbox.backgroundColor = 0x0000FF;
 41        //透明度默认是完全透明,所以必须设定才能让背景色显示出来
 42        __hbox.backgroundAlpha = 0.2;
 43        //让该容器置顶,宽度始终与舞台相同
 44        __hbox.right = 0;
 45        __hbox.left = 0;
 46        __hbox.top = 0;
 47        //让容器中的子显示对象的横向间隔为10像素
 48        __hbox.childrenGap = new GapUI(10);
 49        //让容器中的子显示对象基于容器的右下方对齐
 50        __hbox.childrenAlign = HBoxUI.ALIGN_BOTTOM_RIGHT;
 51        //加入6个shape
 52        for(var i:int=0; i<6; i++)
 53        {
 54            createShape(__hbox);
 55        }
 56        //将容器加入显示列表并刷新容器布局
 57        addChild(__hbox);
 58        __hbox.refresh();
 59        
 60        //增加一个CanvasUI容器
 61        var __canvas:CanvasUI = new CanvasUI(this.stage);
 62        __canvas.backgroundColor = 0xFF0000;
 63        __canvas.backgroundAlpha = .5;
 64        //让canvas在舞台中纵向居中,宽度与舞台宽度始终相同
 65        __canvas.verticalCenter = 0;
 66        __canvas.left = 0;
 67        __canvas.right = 0;
 68        //建立canvas的第1个子显示对象,在canvas中左下对齐
 69        var __shape1:Shape = createShape();
 70        var __element1:ElementUI = __canvas.add(__shape1);
 71        __element1.left = 0;
 72        __element1.bottom = 0;
 73        //建立canvas的第2个子显示对象,在canvas中居中对齐
 74        var __shape2:Shape = createShape();
 75        var __element2:ElementUI = __canvas.add(__shape2);
 76        __element2.horizontalCenter = 0;
 77        __element2.verticalCenter = 0;
 78        //建立canvas的第3个子显示对象,在canvas中右上对齐
 79        var __shape3:Shape = createShape();
 80        var __element3:ElementUI = __canvas.add(__shape3);
 81        __element3.right =0;
 82        addChild(__canvas);
 83        __canvas.refresh();
 84        
 85        this.stage.addEventListener(Event.RESIZE, handler_resize);
 86    }
 87    
 88    private var _baseUI:BaseUI;
 89    
 90    //快速绘制一个Shape用于测试,如果绘制的时候提供了父显示对象,就将其加入父显示对象的显示列表
 91    private function createShape($parent:DisplayObjectContainer=null):Shape
 92    {
 93        var __shape:Shape = new Shape();
 94        __shape.graphics.lineStyle(2, 0xFF0000);
 95        __shape.graphics.drawRect(0, 0 , 30, 30);
 96        if($parent)
 97            $parent.addChild(__shape);
 98        return __shape;
 99    }
100    
101    private function handler_resize(evt:Event):void
102    {
103        trace(stage.stageWidth, stage.stageHeight, stage.width, stage.height);
104    }
105}
106}