开发者

Flex 4 - How to draw a shape to use as a skin for a ButtonBarButton

开发者 https://www.devze.com 2023-03-18 15:34 出处:网络
I\'m using Flash Builder 4 and am in the process of learning. The short and simple explanation is, I want a tab navigator that has tabs that look like this:

I'm using Flash Builder 4 and am in the process of learning.

The short and simple explanation is, I want a tab navigator that has tabs that look like this:

Flex 4 - How to draw a shape to use as a skin for a ButtonBarButton

Flex 4 - How to draw a shape to use as a skin for a ButtonBarButton

I know I could do this using an image-based skin, but I figured (and could be wrong) that programmatically drawing the shape would be better in terms of scalability.

As long as I get the result I'm looking for, I guess I don't really care if it's mx or spark. I tried doing this:

Main App:

<mx:ButtonBar dataProvider="{vsTabNav}" firstButtonStyle="firstButtonStyle"/>

CSS File:

.firstButtonStyle { skinClass:ClassReference("assets.skins.ButtonBarFirstButtonSkin"); }

ButtonBarFirstButtonSkin.as:

package assets.skins
{
    import flash.display.Graphics;
    import mx.skins.halo开发者_C百科.ButtonBarButtonSkin;
    import mx.graphics.RectangularDropShadow;

    public class ButtonBarFirstButtonSkin extends ButtonBarButtonSkin
    {
        private var dropShadow:RectangularDropShadow;

        public function ButtonBarFirstButtonSkin()
        {
            super();
        }

        override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void 
        {
            super.updateDisplayList(unscaledWidth, unscaledHeight);

            var cornerRadius:Number = getStyle("cornerRadius");
            var backgroundColor:int = getStyle("backgroundColor");
            var backgroundAlpha:Number = getStyle("backgroundAlpha");
            graphics.clear();

            cornerRadius = 10;
            backgroundColor = 0xFF0000;
            backgroundAlpha = 1;

            // Background
            drawRoundRect(0, 0, unscaledWidth, unscaledHeight, {tl:1, tr:cornerRadius, bl:1, br:1}, backgroundColor, backgroundAlpha);

            // Shadow
            if (!dropShadow)
                dropShadow = new RectangularDropShadow();

            dropShadow.distance = 8;
            dropShadow.angle = 45;
            dropShadow.color = 0;
            dropShadow.alpha = 0.4;
            dropShadow.tlRadius = 1;
            dropShadow.trRadius = cornerRadius;
            dropShadow.blRadius = 1;
            dropShadow.brRadius = 1;
            dropShadow.drawShadow(graphics, 0, 0, unscaledWidth, unscaledHeight);
        }

    }
}

This should mean that the first button will be red and will have a very round top-right corner. Instead, I just get the default button. Not sure what I'm doing wrong there, but if that's not the best solution, I would love some help. Thanks!


First, have a look at http://www.adobe.com/devnet/flex/articles/flex4_skinning.html

Then, you should realize, you'll be better off creating first skins for your ButtonBarButtons and make sure your button bar uses them for its buttons.

Also, you can create the shapes with the Path class. Following is an example that creates similar shapes to yours:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark" 
               xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
    <s:Path x="10" y="10"
            data="M 0 2 V 18 H 200 Q 190 3 170 0 H 2 L 0 2 Z" 
            width="200" height="20"  >
        <s:fill>
            <s:LinearGradient rotation="90">
                <s:GradientEntry color="0xFFFFFF" />
                <s:GradientEntry color="0xFDFDFD" ratio="0.6" />
                <s:GradientEntry color="0x8A8A8A" ratio="1" />
            </s:LinearGradient>
        </s:fill>
        <s:stroke>
            <s:SolidColorStroke color="0x000000" />
        </s:stroke>
    </s:Path>

    <s:Path x="215" y="10"
            data="M 30 0 Q 10 0 0 20 H 200 Q 190 3 170 0 H 30 Z" 
            width="200" height="20"  >
        <s:fill>
            <s:LinearGradient rotation="90">
                <s:GradientEntry color="0x8f8f8f" />
                <s:GradientEntry color="0x878787" ratio="0.6" />
                <s:GradientEntry color="0x5d5d5d" ratio="1" />
            </s:LinearGradient>
        </s:fill>
        <s:stroke>
            <s:SolidColorStroke color="0x000000" />
        </s:stroke>
    </s:Path>
</s:Application>

UPDATE: If you want scaling, you can put the Path element into a Graphic element, and setup its scaleGrid properties:

<s:Graphic scaleGridTop="1" scaleGridBottom="19" scaleGridLeft="10" scaleGridRight="170"
           width="150" height="15"
           x="10" y="10" 
           >
    <s:Path 
            data="M 0 2 V 18 H 200 Q 190 3 170 0 H 2 L 0 2 Z" 
            width="200" height="20" >
        <s:fill>
            <s:LinearGradient rotation="90">
                <s:GradientEntry color="0xFFFFFF" />
                <s:GradientEntry color="0xFDFDFD" ratio="0.6" />
                <s:GradientEntry color="0x8A8A8A" ratio="1" />
            </s:LinearGradient>
        </s:fill>
        <s:stroke>
            <s:SolidColorStroke color="0x000000" />
        </s:stroke>
    </s:Path>
</s:Graphic>


If that is all you want to achieve - can't you just specify the corner radius values in the CSS style and move on (without a custom skin)?

:)

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号