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部分为加的遮罩.