ActionScript皮肤编程

通过前面三种方法,估计你已经对整个皮肤制作过程有了大概的了解,如果要制作较高级皮肤就得借助ActionScript来实现了。
先来看看CSS中的例句:
upSkin:ClassReference(“UpSkinClass”);
其中UpSkinClass就是我们要实现的皮肤类。
打开Flex Builder 3,在src文件夹下新建skins文件夹,并在skins文件夹下新建类文件:ButtonSkin.as,如下图所示:
我们选择mx.skins.Border作为superclass。
为什么要选择Border类呢?我们先来了解一下几个可以用于皮肤编程的superclass。
ProgrammaticSkin:实现了IFlexDisplayObject,ILayoutManagerClient,IInvalidating,ISimpleStyleClient接口,是最为容易和通用的superclass。
Border: ProgrammaticSkin的子类,并且加入了borderMetrics属性,如果皮肤有border属性可以使用这个类。
RectangularBorder:Border的子类,支持backgroundImage样式。
UIComponent:实现了IStateCleint接口,易于制作多状态的组件皮肤,也是实现MXML皮肤时所需的组件。
以上四个类的详细介绍可参考官方文档。
好了,我们再回到程序中,通过重写Border类的updateDisplayList方法来实现皮肤的重绘:
override protected function updateDisplayList(w:Number, h:Number):void
{
//Draw your Graphics.
}
填充以下代码:
override protected function updateDisplayList(w:Number, h:Number):void
{
var g:Graphics = graphics;
g.clear();
//draw outside border
g.lineStyle(1, 0xFFFFFF, 0.1);
g.drawRect(0, 0, w, h);
//draw
g.lineStyle(1, 0×000000, 0.6);
var gradientBoxMatrix:Matrix = new Matrix();
gradientBoxMatrix.createGradientBox(w, h, Math.PI/2, 0, 0);
g.beginGradientFill(GradientType.LINEAR,[0xFFFFFF, 0xFFFFFF],[0.1,0.0],null,gradientBoxMatrix);
g.drawRect(1, 1, w-2, h-2);
g.endFill();
g.lineGradientStyle(GradientType.LINEAR,[0xFFFFFF, 0xFFFFFF],[0.08,0.03],null,gradientBoxMatrix);
g.drawRect(2, 2, w-4, h-4);
}
保存后打开style.css文件,切换到Source面板,在Button组件样式下加入代码:
upSkin: ClassReference(”skins.ButtonSkin”);
注意类包名要写全。
再切换到Design面板,单击刷新按钮
我们的程序已经起作用了:
那么其他状态呢,每个状态都要写一个类吗?No!
还有一个重要的属性没有使用:name
这个name就是状态实例名称,例如”upSkin”,”overSkin”等。
用switch语句来判断不同的实例名称并进行不同的绘制:
override protected function updateDisplayList(w:Number, h:Number):void
{
var g:Graphics = graphics;
g.clear();
var gradientBoxMatrix:Matrix = new Matrix();
switch(name)
{
case “upSkin”:
{
//draw external border
g.lineStyle(1, 0xFFFFFF, 0.1);
g.drawRect(0, 0, w, h);
//draw inner border and fill in gradual color
g.lineStyle(1, 0×000000, 0.6);
gradientBoxMatrix.createGradientBox(w, h, Math.PI/2, 0, 0);
g.beginGradientFill(GradientType.LINEAR,[0xFFFFFF, 0xFFFFFF],[0.1,0.0],null,gradientBoxMatrix);
g.drawRect(1, 1, w-2, h-2);
g.endFill();
//draw inner high-light border
g.lineGradientStyle(GradientType.LINEAR,[0xFFFFFF, 0xFFFFFF],[0.08,0.03],null,gradientBoxMatrix);
g.drawRect(2, 2, w-4, h-4);
break;
}
case “overSkin”:
{
g.lineStyle(1, 0xFFFFFF, 0.1);
g.drawRect(0, 0, w, h);
g.lineStyle(1, 0×000000, 0.6);
gradientBoxMatrix.createGradientBox(w, h, Math.PI/2, 0, 0);
g.beginGradientFill(GradientType.LINEAR,[0xFFFFFF, 0xFFFFFF],[0.15,0.05],null,gradientBoxMatrix);
g.drawRect(1, 1, w-2, h-2);
g.endFill();
g.lineGradientStyle(GradientType.LINEAR,[0xFFFFFF, 0xFFFFFF],[0.08,0.03],null,gradientBoxMatrix);
g.drawRect(2, 2, w-4, h-4);
break;
}
case “downSkin”:
{
break;
}
case “disabledSkin”:
{
break;
}
case “selectedUpSkin”:
{
break;
}
case “selectedOverSkin”:
{
break;
}
case “selectedDownSkin”:
{
break;
}
case “selectedDisabledSkin”:
{
break;
}
}
}
上示代码只绘制了upSkin和overSkin两个状态的皮肤,其他的皮肤您可以尝试着完成。
如果觉得在样式表中每个状态的皮肤类都要指明很麻烦,可以使用以下语句:
skin: Embed(skinClass=’skins.ButtonSkin’);
或:
skin: ClassReference(”skins.ButtonSkin”);
最后效果如下:
(注:其他样式因为没有实现,所以只显示了Label)
MXML皮肤编程:
此外,我们还可以使用MXML文件来制作皮肤。仍以Button组件制作为例。
打开Flex Builder 3,在FlexSkinTest项目中新建文件夹components,在components文件夹下新建文件夹skins,skins文件夹下新建ButtonSkin.mxml文件:
重写updateDisplayList方法,并填充上个例子中的绘图语句。
//fill in the inner array: alpha
private var _innerFrameAlphas:Array = [0.1,0.0];
//inner high-light alpha
private var _innerHighlightAlphas:Array = [0.08,0.03];
override protected function updateDisplayList(w:Number, h:Number):void
{
var g:Graphics = graphics;
g.clear();
var gradientBoxMatrix:Matrix = new Matrix();
g.lineStyle(1, 0xFFFFFF, 0.1);
g.drawRect(0, 0, w, h);
// draw inner border and fill in gradual color
g.lineStyle(1, 0×000000, 0.6);
gradientBoxMatrix.createGradientBox(w, h, Math.PI/2, 0, 0);
g.beginGradientFill(GradientType.LINEAR,[0xFFFFFF, 0xFFFFFF],_innerFrameAlphas,null,gradientBoxMatrix);
g.drawRect(1, 1, w-2, h-2);
g.endFill();
//draw inner high-light border
g.lineGradientStyle(GradientType.LINEAR,[0xFFFFFF, 0xFFFFFF],_innerHighlightAlphas,null,gradientBoxMatrix);
g.drawRect(2, 2, w-4, h-4);
}
再打开style.css,更改嵌入语句:
skin: ClassReference(”components.skins.ButtonSkin”);
此时可以发现皮肤已经更新了:
但是所有皮肤都是相同的,接下来我们设置不同的属性值区分不同的状态皮肤。
这时就用到了invalidateDisplayList方法,这个方法会呼叫updateDisplayList方法更新组件。
我们把前面的两个变量_innerFrameAlphas和innerHighlightAlphas封装:
public function get innerFrameAlphas():Array
{
return _innerFrameAlphas;
}
public function get innerHighlightAlphas():Array
{
return _innerHighlightAlphas;
}
public function set innerFrameAlphas(alphas:Array):void
{
_innerFrameAlphas = alphas;
invalidateDisplayList();
}
public function set innerHighlightAlphas(alphas:Array):void
{
_innerHighlightAlphas = alphas;
invalidateDisplayList();
}
之后在over这个State中,设置innerFrameAlphas和innerHighlightAlphas属性,重绘组件。
<mx:State name=”over”>
<mx:SetProperty target=”{this}” name=”innerFrameAlphas” value=”{[0.15,0.05]}”/>
<mx:SetProperty target=”{this}” name=”innerHighlightAlphas” value=”{[0.08,0.03]}”/>
</mx:State>
现在我们再发布一下,你会发现over状态的皮肤已经更新了。其余状态的皮肤您可尝试着完成,这里就不复述了。
最后,如果要在运行时加载皮肤,应把皮肤单独编译为SWF文件。
在CSS文件上右键->Comile CSS to SWF即可。
也可通过命令行“mxmlc style.css”来编译。
OK,在FLEX皮肤制作过程中,这几种方法是比较常用的,灵活运用可以使你的程序增色不少。
本文来源于 冰山上的播客 http://xinsync.xju.edu.cn , 原文地址:http://xinsync.xju.edu.cn/index.php/archives/2241

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值