BorderContainer的圆角问题

如上所示(加载比较慢,请耐心等待……),当设置圆角的时候位于角上的内容没有被截断,显示到边框之外了。

为了解决这个问题,写了一个皮肤,给内容部分加个带圆角的遮罩,即点击“切换”按钮之后的效果。

皮肤文件代码:

  1 <?xml version="1.0" encoding="utf-8"?>
  2 <s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009" 
  3         xmlns:s="library://ns.adobe.com/flex/spark" 
  4         xmlns:mx="library://ns.adobe.com/flex/mx" alpha.disabled=".5" alpha="1">
  5     <!-- host component -->
  6     <fx:Metadata>
  7         [HostComponent("spark.components.BorderContainer")]
  8     </fx:Metadata>
  9     
 10     <fx:Script>
 11         <![CDATA[
 12             import mx.graphics.BitmapFill;
 13             import mx.graphics.SolidColor;
 14             import mx.graphics.SolidColorStroke;
 15             
 16             /**
 17              *  @private 
 18              */ 
 19             override protected function measure():void
 20             {        
 21                 measuredWidth = contentGroup.measuredWidth;
 22                 measuredHeight = contentGroup.measuredHeight;
 23                 measuredMinWidth = contentGroup.measuredMinWidth;
 24                 measuredMinHeight = contentGroup.measuredMinHeight;
 25                 
 26                 var borderWeight:Number = getStyle("borderWeight");
 27                 
 28                 if (hostComponent && hostComponent.borderStroke)
 29                     borderWeight = hostComponent.borderStroke.weight;
 30                 
 31                 if (borderWeight > 0)
 32                 {
 33                     var borderSize:int = borderWeight * 2;
 34                     measuredWidth += borderSize;
 35                     measuredHeight += borderSize;
 36                     measuredMinWidth += borderSize;
 37                     measuredMinHeight += borderSize;
 38                 }
 39             }
 40             
 41             /**
 42              *  @private 
 43              */ 
 44             override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number) : void
 45             {
 46                 graphics.clear();
 47                 
 48                 var borderWeight:int;
 49                 var borderStyle:String = getStyle("borderStyle");
 50                 var borderVisible:Boolean = getStyle("borderVisible");
 51                 var cornerRadius:Number = getStyle("cornerRadius");
 52                 
 53                 if (hostComponent && hostComponent.borderStroke)
 54                     borderWeight = hostComponent.borderStroke.weight;
 55                 else
 56                     borderWeight = getStyle("borderWeight"); 
 57                 
 58                 if (!borderVisible)
 59                     borderWeight = 0;
 60                 
 61                 if (isNaN(borderWeight))
 62                     borderWeight = 1;
 63                 
 64                 contentGroup.setStyle("left", borderWeight);
 65                 contentGroup.setStyle("right", borderWeight);
 66                 contentGroup.setStyle("top", borderWeight);
 67                 contentGroup.setStyle("bottom", borderWeight);
 68                 
 69                 // update the bgRect stroke/fill
 70                 if (hostComponent.borderStroke)
 71                 {
 72                     bgRect.stroke = hostComponent.borderStroke;
 73                 }
 74                 else if (!borderVisible)
 75                 {
 76                     bgRect.stroke = null;
 77                 }
 78                 else
 79                 {
 80                     var borderColor:Number = getStyle("borderColor");
 81                     var borderAlpha:Number = getStyle("borderAlpha");
 82                     
 83                     if (!isNaN(borderColor))
 84                     {
 85                         if (isNaN(borderAlpha))
 86                             borderAlpha = 1;
 87                         bgRect.stroke = new SolidColorStroke(borderColor, borderWeight, borderAlpha);
 88                     }
 89                 }
 90                 
 91                 if (hostComponent.backgroundFill)
 92                 {
 93                     bgRect.fill = hostComponent.backgroundFill;
 94                 }
 95                 else
 96                 {
 97                     var bgImage:Object = getStyle("backgroundImage");
 98                     
 99                     if (bgImage)
100                     {
101                         var bitmapFill:BitmapFill = bgRect.fill is BitmapFill ? BitmapFill(bgRect.fill) : new BitmapFill();
102                         
103                         bitmapFill.source = bgImage;
104                         bitmapFill.fillMode = getStyle("backgroundImageFillMode");
105                         bitmapFill.alpha = getStyle("backgroundAlpha");
106                         
107                         bgRect.fill = bitmapFill;
108                     }
109                     else
110                     {
111                         var bkgdColor:Number = getStyle("backgroundColor");
112                         var bkgdAlpha:Number = getStyle("backgroundAlpha");
113                         
114                         if (isNaN(bkgdAlpha))
115                             bkgdAlpha = 1;
116                         
117                         if (!isNaN(bkgdColor))
118                             bgRect.fill = new SolidColor(bkgdColor, bkgdAlpha);
119                         else
120                             bgRect.fill = new SolidColor(0, 0);
121                     }
122                 }
123                 
124                 // Draw the shadow for the inset style
125                 if (borderStyle == "inset" && hostComponent.borderStroke == null && borderVisible)
126                 {            
127                     var negCR:Number = -cornerRadius;
128                     var path:String = ""; 
129                     
130                     if (cornerRadius > 0 && borderWeight < 10)
131                     {
132                         // Draw each corner with two quadratics, using the following ratios:
133                         var a:Number = cornerRadius * 0.292893218813453;
134                         var s:Number = cornerRadius * 0.585786437626905;
135                         var right:Number = unscaledWidth - borderWeight;
136                         
137                         path += "M 0 " + cornerRadius; // M 0 CR
138                         path += " Q 0 " + s + " " + a + " " + a; // Q 0 s a a 
139                         path += " Q " + s + " 0 " + cornerRadius + " 0"; // Q s 0 CR 0
140                         path += " L " + (right - cornerRadius) + " 0"; // L (right-CR) 0
141                         path += " Q " + (right - s) + " 0 " + (right - a) + " " + a; // Q (right-s) 0 (right-a) a
142                         path += " Q " + right + " " + s + " " + right + " " + cornerRadius; // Q right s right CR   
143                         insetPath.height = cornerRadius;
144                     }
145                     else
146                     {
147                         path += "M 0 0";
148                         path += " L " + (unscaledWidth - borderWeight) + " 0";
149                         insetPath.height = 1; 
150                     }
151                     
152                     insetPath.x = borderWeight;
153                     insetPath.y = borderWeight;
154                     insetPath.width = unscaledWidth - (borderWeight * 2);
155                     insetPath.data = path;
156                     insetPath.stroke = new SolidColorStroke(0x000000, 1, .12);
157                 }
158                 else
159                 {
160                     insetPath.data = "";
161                     insetPath.stroke = null;
162                 }
163                 
164                 bgRect.radiusX = bgRect.radiusY = cornerRadius; 
165                 
166                 // mask
167                 var shape:Shape = new Shape();
168                 var g:Graphics = shape.graphics;
169                 
170                 g.clear();
171                 g.beginFill(1);
172                 g.drawRoundRect(0, 0, unscaledWidth, unscaledHeight, cornerRadius, cornerRadius);
173                 g.endFill();
174                 
175                 contentGroup.mask = shape;
176                 
177                 super.updateDisplayList(unscaledWidth, unscaledHeight);
178                 
179                 if (getStyle("dropShadowVisible") == true)
180                 {
181                     rds.alpha = 0.4;
182                     rds.angle = 90;
183                     rds.color = 0x000000;
184                     rds.distance = 5;
185                     rds.tlRadius = rds.trRadius = rds.blRadius = rds.brRadius = cornerRadius + 1;
186                     
187                     graphics.lineStyle();
188                     rds.width = unscaledWidth;
189                     rds.height = unscaledHeight;
190                 }
191             }
192         ]]>
193     </fx:Script>
194     
195     <!-- states -->
196     <s:states>
197         <s:State name="normal" />
198         <s:State name="disabled"/>
199     </s:states>
200     
201     <s:Rect id="bgRect" left="0" right="0" top="0" bottom="0">
202     </s:Rect>
203     
204     <!-- SkinParts
205     name=contentGroup, type=spark.components.Group, required=false
206     -->
207     <s:Group id="contentGroup"/>
208     
209     <s:Path id="insetPath"/>
210     
211     <s:RectangularDropShadow id="rds"/>
212 </s:Skin>

具体就不解释了,大部分都是拷贝自BorderContainer的默认皮肤文件:spark.skins.spark.BorderContainerSkin,只有注释了mask部分为加的遮罩.

posted on 2012-05-14 10:58  lipbb  阅读(1079)  评论(0编辑  收藏  举报

导航