2009-09-06

HDividedBox与VDividedBox的分隔条样式设定

Flex的HDividedBox与VDividedBox组件的分隔条样式比较单一,默认是三条横线或竖线(mx.skin.BoxDividerSkin类,包含在Assets.swf文件中),且不能设置分隔条的整体颜色。当然,可以通过设置样式dividerSkin改变那三条线的默认样式。不过看mx.containers.dividedBoxClasses.BoxDivider的代码,显示时对于横向与纵向分隔,只是简单地旋转dividerSkin,因此稍复杂一些的dividerSkin效果应该不会太好,很有必要设置两个dividerSkin,横向纵向各一个,专款专用。此外,可以考虑再给分隔条加一个背景皮肤。

  接下来写需要的几个皮肤,分隔条背景皮肤是淡蓝色的渐变填充外加一个深蓝色边框,knob皮肤(替代dividerSkin的那个)是两排蓝白色小点。

  1) 纵向分隔条背景皮肤:

  1. package com.ccac.ibs.skins.common  
  2. {  
  3.       
  4.     import flash.display.GradientType;  
  5.     import flash.display.Graphics;  
  6.     import flash.display.InterpolationMethod;  
  7.     import flash.display.SpreadMethod;  
  8.     import flash.geom.Matrix;  
  9.       
  10.     import mx.skins.ProgrammaticSkin;  
  11.       
  12.     public class IBSVBoxDividerSkin extends ProgrammaticSkin  
  13.     {  
  14.           
  15.         public function IBSVBoxDividerSkin()  
  16.         {  
  17.             super();  
  18.         }  
  19.           
  20.         override protected function updateDisplayList(w:Number, h:Number):void  
  21.         {  
  22.             var g:Graphics = graphics;  
  23.             var matrix:Matrix = new Matrix();  
  24.             if (isNaN(w) || isNaN(h))  
  25.                 return;   
  26.             g.clear();  
  27.             g.lineStyle(10x6593CF1);  
  28.             g.beginFill(0xFFFFFF0);  
  29.             g.drawRect(00, w - 1, h - 1);  
  30.             g.endFill();  
  31.             matrix.createGradientBox(w - 2, h - 2, Math.PI / 200);  
  32.             g.lineStyle(00x0000000);  
  33.             g.beginGradientFill(GradientType.LINEAR,   
  34.                     [0xFFFFFF0xF8FBFF0xF0F7FF0xE5F1FF0xDAEBFF0xD0E5FF],   
  35.                     [111111],   
  36.                     [051102153204255],   
  37.                     matrix,   
  38.                     SpreadMethod.PAD,   
  39.                     InterpolationMethod.LINEAR_RGB,   
  40.                     0);  
  41.             g.drawRect(11, w - 2, h - 2);  
  42.             g.endFill();  
  43.         }  
  44.           
  45.     }  
  46.       
  47. }  


  2) 纵向分隔条knob皮肤:

  1. package com.ccac.ibs.skins.common  
  2. {  
  3.       
  4.     import flash.display.Graphics;  
  5.       
  6.     import mx.skins.ProgrammaticSkin;  
  7.       
  8.     public class IBSVDividerSkin extends ProgrammaticSkin  
  9.     {  
  10.           
  11.         public function IBSVDividerSkin()  
  12.         {  
  13.             super();  
  14.         }  
  15.           
  16.         override public function get measuredWidth():Number  
  17.         {  
  18.             return 23;  
  19.         }  
  20.           
  21.         override public function get measuredHeight():Number  
  22.         {  
  23.             return 6;  
  24.         }  
  25.           
  26.         override protected function updateDisplayList(w:Number, h:Number):void  
  27.         {  
  28.             var g:Graphics = this.graphics;  
  29.             var i:int = 0;  
  30.             g.clear();  
  31.             g.lineStyle(00x0000000);  
  32.             g.beginFill(0x6593CF1);  
  33.             for (i = 0; i < 5; i++)  
  34.             {  
  35.                 g.drawRect(2 + (i - 1) * 4222);  
  36.             }  
  37.             g.endFill();  
  38.             g.beginFill(0xF9F9FB1);  
  39.             for (i = 0; i < 5; i++)  
  40.             {  
  41.                 g.drawRect(3 + (i - 1) * 4322);  
  42.             }  
  43.             g.endFill();  
  44.             g.beginFill(0xADD1FF1);  
  45.             for (i = 0; i < 5; i++)  
  46.             {  
  47.                 g.drawRect(3 + (i - 1) * 4311);  
  48.             }  
  49.             g.endFill();  
  50.         }  
  51.           
  52.     }  
  53.       
  54. }  


  3) 横向分隔条背景皮肤:

  1. package com.ccac.ibs.skins.common  
  2. {  
  3.       
  4.     import flash.display.GradientType;  
  5.     import flash.display.Graphics;  
  6.     import flash.display.InterpolationMethod;  
  7.     import flash.display.SpreadMethod;  
  8.     import flash.geom.Matrix;  
  9.       
  10.     import mx.skins.ProgrammaticSkin;  
  11.       
  12.     public class IBSHBoxDividerSkin extends ProgrammaticSkin  
  13.     {  
  14.           
  15.         public function IBSHBoxDividerSkin()  
  16.         {  
  17.             super();  
  18.         }  
  19.           
  20.         override protected function updateDisplayList(w:Number, h:Number):void  
  21.         {  
  22.             var g:Graphics = graphics;  
  23.             var matrix:Matrix = new Matrix();  
  24.             if (isNaN(w) || isNaN(h))  
  25.                 return;   
  26.             g.clear();  
  27.             g.lineStyle(10x6593CF1);  
  28.             g.beginFill(0xFFFFFF0);  
  29.             g.drawRect(00, w - 1, h - 1);  
  30.             g.endFill();  
  31.             matrix.createGradientBox(w - 2, h - 2000);  
  32.             g.lineStyle(00x0000000);  
  33.             g.beginGradientFill(GradientType.LINEAR,   
  34.                     [0xFFFFFF0xF8FBFF0xF0F7FF0xE5F1FF0xDAEBFF0xD0E5FF],   
  35.                     [111111],   
  36.                     [051102153204255],   
  37.                     matrix,   
  38.                     SpreadMethod.PAD,   
  39.                     InterpolationMethod.LINEAR_RGB,   
  40.                     0);  
  41.             g.drawRect(11, w - 2, h - 2);  
  42.             g.endFill();  
  43.         }  
  44.           
  45.     }  
  46.       
  47. }  


  4) 横向分隔条knob皮肤:

  1. package com.ccac.ibs.skins.common  
  2. {  
  3.       
  4.     import flash.display.Graphics;  
  5.       
  6.     import mx.skins.ProgrammaticSkin;  
  7.       
  8.     public class IBSHDividerSkin extends ProgrammaticSkin  
  9.     {  
  10.           
  11.         public function IBSHDividerSkin()  
  12.         {  
  13.             super();  
  14.         }  
  15.           
  16.         override public function get measuredWidth():Number  
  17.         {  
  18.             return 6;  
  19.         }  
  20.           
  21.         override public function get measuredHeight():Number  
  22.         {  
  23.             return 23;  
  24.         }  
  25.           
  26.         override protected function updateDisplayList(w:Number, h:Number):void  
  27.         {  
  28.             var g:Graphics = this.graphics;  
  29.             var i:int = 0;  
  30.             g.clear();  
  31.             g.lineStyle(00x0000000);  
  32.             g.beginFill(0x6593CF1);  
  33.             for (i = 0; i < 5; i++)  
  34.             {  
  35.                 g.drawRect(22 + (i - 1) * 422);  
  36.             }  
  37.             g.endFill();  
  38.             g.beginFill(0xF9F9FB1);  
  39.             for (i = 0; i < 5; i++)  
  40.             {  
  41.                 g.drawRect(33 + (i - 1) * 422);  
  42.             }  
  43.             g.endFill();  
  44.             g.beginFill(0xADD1FF1);  
  45.             for (i = 0; i < 5; i++)  
  46.             {  
  47.                 g.drawRect(33 + (i - 1) * 411);  
  48.             }  
  49.             g.endFill();  
  50.         }  
  51.           
  52.     }  
  53.       
  54. }  


  接下来定义一个继承自BoxDivider的类,并覆盖其updateDisplayList方法,显示自定义的皮肤(hSkin,vSkin,hDividerSkin,vDividerSkin),如果这几个样式属性都取不到,就按父类方法显示,也就是显示dividerSkin。代码如下:

  1. package com.ccac.ibs.containers.dividedBoxClasses  
  2. {  
  3.       
  4.     import flash.display.DisplayObject;  
  5.       
  6.     import mx.containers.DividedBox;  
  7.     import mx.containers.DividerState;  
  8.     import mx.containers.dividedBoxClasses.BoxDivider;  
  9.     import mx.core.mx_internal;  
  10.     import mx.skins.ProgrammaticSkin;  
  11.       
  12.     use namespace mx_internal;  
  13.       
  14.     public class IBSBoxDivider extends BoxDivider  
  15.     {  
  16.           
  17.         public function IBSBoxDivider()  
  18.         {  
  19.             super();  
  20.         }  
  21.           
  22.         private var divider:DisplayObject = null;  
  23.           
  24.         private var knob:DisplayObject = null;  
  25.           
  26.         override protected function updateDisplayList(unscaledWidth:Number,   
  27.                 unscaledHeight:Number):void  
  28.         {  
  29.             if (isNaN(width) || isNaN(height))  
  30.                 return;  
  31.             if (!parent)  
  32.                 return;  
  33.             graphics.clear();  
  34.             var color:Number = 0;  
  35.             var alpha:Number = 1.0;  
  36.             var thickness:Number = getStyle("dividerThickness");  
  37.             var vertical:Boolean = DividedBox(owner).isVertical();  
  38.             var gap:Number = vertical ?   
  39.                     DividedBox(owner).getStyle("verticalGap") :   
  40.                     DividedBox(owner).getStyle("horizontalGap");  
  41.             var dividerClass:Class = null;  
  42.             var knobClass:Class = null;  
  43.             if (state != DividerState.DOWN)  
  44.             {  
  45.                 dividerClass = Class(vertical ? getStyle("vSkin") :   
  46.                         getStyle("hSkin"));  
  47.                 knobClass = Class(vertical ? getStyle("vDividerSkin") :   
  48.                         getStyle("hDividerSkin"));  
  49.                 if (!dividerClass && !knobClass)  
  50.                 {  
  51.                     super.updateDisplayList(unscaledWidth, unscaledHeight);  
  52.                     return;  
  53.                 }  
  54.                 if (!divider)  
  55.                 {  
  56.                     if (dividerClass)  
  57.                         divider = new dividerClass();  
  58.                     if (divider)  
  59.                         addChildAt(divider, 0);  
  60.                 }  
  61.                 else  
  62.                 {  
  63.                     if (dividerClass && !(divider is dividerClass))  
  64.                     {  
  65.                         removeChild(divider);  
  66.                         divider = new dividerClass();  
  67.                         if (divider)  
  68.                             addChildAt(divider, 0);  
  69.                     }  
  70.                 }  
  71.                 if (divider)  
  72.                 {  
  73.                     divider.width = unscaledWidth;  
  74.                     divider.height = unscaledHeight;  
  75.                     if (divider is ProgrammaticSkin)  
  76.                     {  
  77.                         (divider as ProgrammaticSkin).invalidateSize();  
  78.                         (divider as ProgrammaticSkin).invalidateDisplayList();  
  79.                     }  
  80.                 }  
  81.                 if (gap >= 6)  
  82.                 {  
  83.                     if (!knob)  
  84.                     {  
  85.                         if (knobClass)  
  86.                             knob = new knobClass();  
  87.                         if (knob)  
  88.                             addChild(knob);  
  89.                     }  
  90.                     else  
  91.                     {  
  92.                         if (knobClass && !(knob is knobClass))  
  93.                         {  
  94.                             removeChild(knob);  
  95.                             knob = new knobClass();  
  96.                             if (knob)  
  97.                                 addChild(knob);  
  98.                         }  
  99.                     }  
  100.                     if (knob)  
  101.                     {  
  102.                         knob.x = Math.round((width - knob.width) / 2);  
  103.                         knob.y = Math.round((height - knob.height) / 2);  
  104.                     }  
  105.                 }  
  106.                 return;  
  107.             }  
  108.             color = getStyle("dividerColor");  
  109.             alpha = getStyle("dividerAlpha");  
  110.             graphics.beginFill(color, alpha);  
  111.             if (vertical)  
  112.             {  
  113.                 var visibleHeight:Number = thickness;  
  114.                 if (visibleHeight > gap)  
  115.                     visibleHeight = gap;  
  116.                 var y:Number = (height - visibleHeight) / 2;  
  117.                 graphics.drawRect(0, y, width, visibleHeight);  
  118.             }  
  119.             else  
  120.             {  
  121.                 var visibleWidth:Number = thickness;  
  122.                 if (visibleWidth > gap)  
  123.                     visibleWidth = gap;  
  124.                 var x:Number = (width - visibleWidth) / 2;  
  125.                 graphics.drawRect(x, 0, visibleWidth, height);  
  126.             }  
  127.             graphics.endFill();  
  128.         }  
  129.           
  130.     }  
  131.       
  132. }  


  还需要一个继承自DividedBox的类,将其dividerClass属性设为IBSBoxDivider,并加入hSkin,vSkin,hDividerSkin,vDividerSkin这几个样式属性。代码如下:

  1. package com.ccac.ibs.containers  
  2. {  
  3.       
  4.     import com.ccac.ibs.containers.dividedBoxClasses.IBSBoxDivider;  
  5.     import com.ccac.ibs.skins.common.IBSHBoxDividerSkin;  
  6.     import com.ccac.ibs.skins.common.IBSHDividerSkin;  
  7.     import com.ccac.ibs.skins.common.IBSVBoxDividerSkin;  
  8.     import com.ccac.ibs.skins.common.IBSVDividerSkin;  
  9.       
  10.     import mx.containers.DividedBox;  
  11.       
  12.     [Style(name="hSkin", type="Class", inherit="no")]  
  13.       
  14.     [Style(name="vSkin", type="Class", inherit="no")]  
  15.       
  16.     [Style(name="hDividerSkin", type="Class", inherit="no")]  
  17.       
  18.     [Style(name="vDividerSkin", type="Class", inherit="no")]  
  19.       
  20.     public class IBSDividedBox extends DividedBox  
  21.     {  
  22.           
  23.         public function IBSDividedBox()  
  24.         {  
  25.             super();  
  26.             this.dividerClass = IBSBoxDivider;  
  27.             /*this.setStyle("hSkin", IBSHBoxDividerSkin); 
  28.             this.setStyle("vSkin", IBSVBoxDividerSkin); 
  29.             this.setStyle("hDividerSkin", IBSHDividerSkin); 
  30.             this.setStyle("vDividerSkin", IBSVDividerSkin);*/  
  31.         }  
  32.           
  33.     }  
  34.       
  35. }  


  注释掉了几行代码,因为这些完全可以在CSS文件里设置,而且不设置的话,是和DividedBox的默认显示样式相同的。

  此外,还需要定义继承自IBSDividedBox的VDividedBox和HDividedBox类:

  VDividedBox:

  1. package com.ccac.ibs.containers  
  2. {  
  3.       
  4.     import mx.containers.BoxDirection;  
  5.     import mx.core.mx_internal;  
  6.       
  7.     public class IBSVDividedBox extends IBSDividedBox  
  8.     {  
  9.           
  10.         public function IBSVDividedBox()  
  11.         {  
  12.             super();  
  13.             mx_internal::layoutObject.direction = BoxDirection.VERTICAL;  
  14.         }  
  15.           
  16.         override public function set direction(value:String):void  
  17.         {  
  18.         }  
  19.           
  20.     }  
  21.       
  22. }  


  HDividedBox:

  1. package com.ccac.ibs.containers  
  2. {  
  3.       
  4.     import mx.containers.BoxDirection;  
  5.     import mx.core.mx_internal;  
  6.       
  7.     public class IBSHDividedBox extends IBSDividedBox  
  8.     {  
  9.           
  10.         public function IBSHDividedBox()  
  11.         {  
  12.             super();  
  13.             mx_internal::layoutObject.direction = BoxDirection.HORIZONTAL;  
  14.         }  
  15.           
  16.         override public function set direction(value:String):void  
  17.         {  
  18.         }  
  19.           
  20.     }  
  21.       
  22. }  


  结束了。写个例子看下效果:

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"   
  3.     xmlns:co="com.ccac.ibs.containers.*"   
  4.     layout="absolute"   
  5.     backgroundColor="#E3EFFF">  
  6.       
  7.     <mx:Style>  
  8.         IBSDividedBox  
  9.         {  
  10.             hSkin: ClassReference("com.ccac.ibs.skins.common.IBSHBoxDividerSkin");  
  11.             vSkin: ClassReference("com.ccac.ibs.skins.common.IBSVBoxDividerSkin");  
  12.             hDividerSkin: ClassReference("com.ccac.ibs.skins.common.IBSHDividerSkin");  
  13.             vDividerSkin: ClassReference("com.ccac.ibs.skins.common.IBSVDividerSkin");  
  14.             dividerColor: #FF0000;  
  15.             dividerAlpha: 0.7;  
  16.             dividerAffordance: 8;  
  17.             dividerThickness: 8;  
  18.             horizontalGap: 8;  
  19.             verticalGap: 8;  
  20.         }  
  21.     </mx:Style>  
  22.       
  23.     <co:IBSVDividedBox width="100%" height="100%">  
  24.         <mx:HBox width="100%" height="50" />  
  25.         <co:IBSHDividedBox width="100%" height="100%">  
  26.             <mx:VBox width="350" height="100%" />  
  27.             <mx:VBox width="100%" height="100%" />  
  28.         </co:IBSHDividedBox>  
  29.     </co:IBSVDividedBox>  
  30.       
  31. </mx:Application>  

没有评论: