Flex的HDividedBox与VDividedBox组件的分隔条样式比较单一,默认是三条横线或竖线(mx.skin.BoxDividerSkin类,包含在Assets.swf文件中),且不能设置分隔条的整体颜色。当然,可以通过设置样式dividerSkin改变那三条线的默认样式。不过看mx.containers.dividedBoxClasses.BoxDivider的代码,显示时对于横向与纵向分隔,只是简单地旋转dividerSkin,因此稍复杂一些的dividerSkin效果应该不会太好,很有必要设置两个dividerSkin,横向纵向各一个,专款专用。此外,可以考虑再给分隔条加一个背景皮肤。
接下来写需要的几个皮肤,分隔条背景皮肤是淡蓝色的渐变填充外加一个深蓝色边框,knob皮肤(替代dividerSkin的那个)是两排蓝白色小点。
1) 纵向分隔条背景皮肤:
package com.ccac.ibs.skins.common
{
import flash.display.GradientType;
import flash.display.Graphics;
import flash.display.InterpolationMethod;
import flash.display.SpreadMethod;
import flash.geom.Matrix;
import mx.skins.ProgrammaticSkin;
public class IBSVBoxDividerSkin extends ProgrammaticSkin
{
public function IBSVBoxDividerSkin()
{
super();
}
override protected function updateDisplayList(w:Number, h:Number):void
{
var g:Graphics = graphics;
var matrix:Matrix = new Matrix();
if (isNaN(w) || isNaN(h))
return;
g.clear();
g.lineStyle(1, 0x6593CF, 1);
g.beginFill(0xFFFFFF, 0);
g.drawRect(0, 0, w - 1, h - 1);
g.endFill();
matrix.createGradientBox(w - 2, h - 2, Math.PI / 2, 0, 0);
g.lineStyle(0, 0x000000, 0);
g.beginGradientFill(GradientType.LINEAR,
[0xFFFFFF, 0xF8FBFF, 0xF0F7FF, 0xE5F1FF, 0xDAEBFF, 0xD0E5FF],
[1, 1, 1, 1, 1, 1],
[0, 51, 102, 153, 204, 255],
matrix,
SpreadMethod.PAD,
InterpolationMethod.LINEAR_RGB,
0);
g.drawRect(1, 1, w - 2, h - 2);
g.endFill();
}
}
}
2) 纵向分隔条knob皮肤:
package com.ccac.ibs.skins.common
{
import flash.display.Graphics;
import mx.skins.ProgrammaticSkin;
public class IBSVDividerSkin extends ProgrammaticSkin
{
public function IBSVDividerSkin()
{
super();
}
override public function get measuredWidth():Number
{
return 23;
}
override public function get measuredHeight():Number
{
return 6;
}
override protected function updateDisplayList(w:Number, h:Number):void
{
var g:Graphics = this.graphics;
var i:int = 0;
g.clear();
g.lineStyle(0, 0x000000, 0);
g.beginFill(0x6593CF, 1);
for (i = 0; i < 5; i++)
{
g.drawRect(2 + (i - 1) * 4, 2, 2, 2);
}
g.endFill();
g.beginFill(0xF9F9FB, 1);
for (i = 0; i < 5; i++)
{
g.drawRect(3 + (i - 1) * 4, 3, 2, 2);
}
g.endFill();
g.beginFill(0xADD1FF, 1);
for (i = 0; i < 5; i++)
{
g.drawRect(3 + (i - 1) * 4, 3, 1, 1);
}
g.endFill();
}
}
}
3) 横向分隔条背景皮肤:
package com.ccac.ibs.skins.common
{
import flash.display.GradientType;
import flash.display.Graphics;
import flash.display.InterpolationMethod;
import flash.display.SpreadMethod;
import flash.geom.Matrix;
import mx.skins.ProgrammaticSkin;
public class IBSHBoxDividerSkin extends ProgrammaticSkin
{
public function IBSHBoxDividerSkin()
{
super();
}
override protected function updateDisplayList(w:Number, h:Number):void
{
var g:Graphics = graphics;
var matrix:Matrix = new Matrix();
if (isNaN(w) || isNaN(h))
return;
g.clear();
g.lineStyle(1, 0x6593CF, 1);
g.beginFill(0xFFFFFF, 0);
g.drawRect(0, 0, w - 1, h - 1);
g.endFill();
matrix.createGradientBox(w - 2, h - 2, 0, 0, 0);
g.lineStyle(0, 0x000000, 0);
g.beginGradientFill(GradientType.LINEAR,
[0xFFFFFF, 0xF8FBFF, 0xF0F7FF, 0xE5F1FF, 0xDAEBFF, 0xD0E5FF],
[1, 1, 1, 1, 1, 1],
[0, 51, 102, 153, 204, 255],
matrix,
SpreadMethod.PAD,
InterpolationMethod.LINEAR_RGB,
0);
g.drawRect(1, 1, w - 2, h - 2);
g.endFill();
}
}
}
4) 横向分隔条knob皮肤:
package com.ccac.ibs.skins.common
{
import flash.display.Graphics;
import mx.skins.ProgrammaticSkin;
public class IBSHDividerSkin extends ProgrammaticSkin
{
public function IBSHDividerSkin()
{
super();
}
override public function get measuredWidth():Number
{
return 6;
}
override public function get measuredHeight():Number
{
return 23;
}
override protected function updateDisplayList(w:Number, h:Number):void
{
var g:Graphics = this.graphics;
var i:int = 0;
g.clear();
g.lineStyle(0, 0x000000, 0);
g.beginFill(0x6593CF, 1);
for (i = 0; i < 5; i++)
{
g.drawRect(2, 2 + (i - 1) * 4, 2, 2);
}
g.endFill();
g.beginFill(0xF9F9FB, 1);
for (i = 0; i < 5; i++)
{
g.drawRect(3, 3 + (i - 1) * 4, 2, 2);
}
g.endFill();
g.beginFill(0xADD1FF, 1);
for (i = 0; i < 5; i++)
{
g.drawRect(3, 3 + (i - 1) * 4, 1, 1);
}
g.endFill();
}
}
}
接下来定义一个继承自BoxDivider的类,并覆盖其updateDisplayList方法,显示自定义的皮肤(hSkin,vSkin,hDividerSkin,vDividerSkin),如果这几个样式属性都取不到,就按父类方法显示,也就是显示dividerSkin。代码如下:
package com.ccac.ibs.containers.dividedBoxClasses
{
import flash.display.DisplayObject;
import mx.containers.DividedBox;
import mx.containers.DividerState;
import mx.containers.dividedBoxClasses.BoxDivider;
import mx.core.mx_internal;
import mx.skins.ProgrammaticSkin;
use namespace mx_internal;
public class IBSBoxDivider extends BoxDivider
{
public function IBSBoxDivider()
{
super();
}
private var divider:DisplayObject = null;
private var knob:DisplayObject = null;
override protected function updateDisplayList(unscaledWidth:Number,
unscaledHeight:Number):void
{
if (isNaN(width) || isNaN(height))
return;
if (!parent)
return;
graphics.clear();
var color:Number = 0;
var alpha:Number = 1.0;
var thickness:Number = getStyle("dividerThickness");
var vertical:Boolean = DividedBox(owner).isVertical();
var gap:Number = vertical ?
DividedBox(owner).getStyle("verticalGap") :
DividedBox(owner).getStyle("horizontalGap");
var dividerClass:Class = null;
var knobClass:Class = null;
if (state != DividerState.DOWN)
{
dividerClass = Class(vertical ? getStyle("vSkin") :
getStyle("hSkin"));
knobClass = Class(vertical ? getStyle("vDividerSkin") :
getStyle("hDividerSkin"));
if (!dividerClass && !knobClass)
{
super.updateDisplayList(unscaledWidth, unscaledHeight);
return;
}
if (!divider)
{
if (dividerClass)
divider = new dividerClass();
if (divider)
addChildAt(divider, 0);
}
else
{
if (dividerClass && !(divider is dividerClass))
{
removeChild(divider);
divider = new dividerClass();
if (divider)
addChildAt(divider, 0);
}
}
if (divider)
{
divider.width = unscaledWidth;
divider.height = unscaledHeight;
if (divider is ProgrammaticSkin)
{
(divider as ProgrammaticSkin).invalidateSize();
(divider as ProgrammaticSkin).invalidateDisplayList();
}
}
if (gap >= 6)
{
if (!knob)
{
if (knobClass)
knob = new knobClass();
if (knob)
addChild(knob);
}
else
{
if (knobClass && !(knob is knobClass))
{
removeChild(knob);
knob = new knobClass();
if (knob)
addChild(knob);
}
}
if (knob)
{
knob.x = Math.round((width - knob.width) / 2);
knob.y = Math.round((height - knob.height) / 2);
}
}
return;
}
color = getStyle("dividerColor");
alpha = getStyle("dividerAlpha");
graphics.beginFill(color, alpha);
if (vertical)
{
var visibleHeight:Number = thickness;
if (visibleHeight > gap)
visibleHeight = gap;
var y:Number = (height - visibleHeight) / 2;
graphics.drawRect(0, y, width, visibleHeight);
}
else
{
var visibleWidth:Number = thickness;
if (visibleWidth > gap)
visibleWidth = gap;
var x:Number = (width - visibleWidth) / 2;
graphics.drawRect(x, 0, visibleWidth, height);
}
graphics.endFill();
}
}
}
还需要一个继承自DividedBox的类,将其dividerClass属性设为IBSBoxDivider,并加入hSkin,vSkin,hDividerSkin,vDividerSkin这几个样式属性。代码如下:
package com.ccac.ibs.containers
{
import com.ccac.ibs.containers.dividedBoxClasses.IBSBoxDivider;
import com.ccac.ibs.skins.common.IBSHBoxDividerSkin;
import com.ccac.ibs.skins.common.IBSHDividerSkin;
import com.ccac.ibs.skins.common.IBSVBoxDividerSkin;
import com.ccac.ibs.skins.common.IBSVDividerSkin;
import mx.containers.DividedBox;
[Style(name="hSkin", type="Class", inherit="no")]
[Style(name="vSkin", type="Class", inherit="no")]
[Style(name="hDividerSkin", type="Class", inherit="no")]
[Style(name="vDividerSkin", type="Class", inherit="no")]
public class IBSDividedBox extends DividedBox
{
public function IBSDividedBox()
{
super();
this.dividerClass = IBSBoxDivider;
/*this.setStyle("hSkin", IBSHBoxDividerSkin);
this.setStyle("vSkin", IBSVBoxDividerSkin);
this.setStyle("hDividerSkin", IBSHDividerSkin);
this.setStyle("vDividerSkin", IBSVDividerSkin);*/
}
}
}
注释掉了几行代码,因为这些完全可以在CSS文件里设置,而且不设置的话,是和DividedBox的默认显示样式相同的。
此外,还需要定义继承自IBSDividedBox的VDividedBox和HDividedBox类:
VDividedBox:
package com.ccac.ibs.containers
{
import mx.containers.BoxDirection;
import mx.core.mx_internal;
public class IBSVDividedBox extends IBSDividedBox
{
public function IBSVDividedBox()
{
super();
mx_internal::layoutObject.direction = BoxDirection.VERTICAL;
}
override public function set direction(value:String):void
{
}
}
}
HDividedBox:
package com.ccac.ibs.containers
{
import mx.containers.BoxDirection;
import mx.core.mx_internal;
public class IBSHDividedBox extends IBSDividedBox
{
public function IBSHDividedBox()
{
super();
mx_internal::layoutObject.direction = BoxDirection.HORIZONTAL;
}
override public function set direction(value:String):void
{
}
}
}
结束了。写个例子看下效果:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:co="com.ccac.ibs.containers.*"
layout="absolute"
backgroundColor="#E3EFFF">
<mx:Style>
IBSDividedBox
{
hSkin: ClassReference("com.ccac.ibs.skins.common.IBSHBoxDividerSkin");
vSkin: ClassReference("com.ccac.ibs.skins.common.IBSVBoxDividerSkin");
hDividerSkin: ClassReference("com.ccac.ibs.skins.common.IBSHDividerSkin");
vDividerSkin: ClassReference("com.ccac.ibs.skins.common.IBSVDividerSkin");
dividerColor: #FF0000;
dividerAlpha: 0.7;
dividerAffordance: 8;
dividerThickness: 8;
horizontalGap: 8;
verticalGap: 8;
}
</mx:Style>
<co:IBSVDividedBox width="100%" height="100%">
<mx:HBox width="100%" height="50" />
<co:IBSHDividedBox width="100%" height="100%">
<mx:VBox width="350" height="100%" />
<mx:VBox width="100%" height="100%" />
</co:IBSHDividedBox>
</co:IBSVDividedBox>
</mx:Application>