Discussion Board

ask questions, discuss topics, solve problems

This is a public Discussion Area  publicRSS

Thread

  • [Tutorial] Custom Button Skin - Adobe Flex
    Thread posted 06/12/09 by Adrian Pirvulescu
    2520 Views, 0 Comments
    Title:
    [Tutorial] Custom Button Skin - Adobe Flex
    Content:

    How to create a custom button skin in a Flex web application?


    That's a common question but a simple google will not reveal so much info on how to do it.
    The limitation with default flex skin is that even we can define as many colors we want in
    a "gradient fill" the "ButtonSkin" will take in consideration only the first 2 of them.

    Why did they made it like this ? donno, and do not care because we can extend the existing skin and created a custom skin for buttons.

    Here is how it does look:

    flex button skin

    Yes.. this is a flex button.

    See interactive demo here

    So... iIn more details,  this is what have we done in 4 easy steps:

    Step 1. Extended the default mx.skins.halo.ButtonSkin class and overrided the updateDisplayList() method that is in charge of "drawing" the button skin.

    CustomButtonSkin.as     >>>Download flex tutorial project

    package skins
    {
    import flash.display.GradientType;
    import mx.skins.halo.ButtonSkin;

    public class CustomButtonSkin extends ButtonSkin
    {
    public function CustomButtonSkin()
    {
    super();
    }

    override protected function updateDisplayList(w:Number, h:Number):void
    {
    super.updateDisplayList(w,h);

    // User-defined styles.
    var outBorderColors:Array = getStyle("outBorderColors");
    var inBorderColors:Array = getStyle("inBorderColors");

    var cornerRadius:Number = getStyle("cornerRadius");

    var upFillAlphas:Array = getStyle("upFillAlphas");
    var upFillColors:Array = getStyle("upFillColors");
    var upFillRatios:Array = getStyle("upFillRatios");

    var overFillAlphas:Array = getStyle("overFillAlphas");
    var overFillColors:Array = getStyle("overFillColors");
    var overFillRatios:Array = getStyle("overFillRatios");

    var downFillAlphas:Array = getStyle("downFillAlphas");
    var downFillColors:Array = getStyle("downFillColors");
    var downFillRatios:Array = getStyle("downFillRatios");

    var cr:Number = Math.max(0, cornerRadius);
    var cr1:Number = Math.max(0, cornerRadius - 1);
    var cr2:Number = Math.max(0, cornerRadius - 2);


    graphics.clear();

    // button border/edge
    drawRoundRect(
    0, 0, w, h, cr,
    outBorderColors, [1,1],
    verticalGradientMatrix(0, 0, w, h ),
    GradientType.LINEAR, [0,255]);
    drawRoundRect(
    1, 1, w-2, h-2, cr1,
    inBorderColors, [1,1],
    verticalGradientMatrix(0, 0, w, h ),
    GradientType.LINEAR, [0,255]);

    switch (name)
    {
    case "selectedUpSkin":
    case "selectedOverSkin":
    {
    // button fill
    drawRoundRect(
    2, 2, w - 4, h - 4, cr2,
    downFillColors, downFillAlphas,
    verticalGradientMatrix(0, 0, w - 2, h - 2),
    GradientType.LINEAR, downFillRatios);

    break;
    }
    case "upSkin":
    {
    // button fill
    drawRoundRect(
    2, 2, w - 4, h - 4, cr2,
    upFillColors, upFillAlphas,
    verticalGradientMatrix(0, 0, w - 2, h - 2),
    GradientType.LINEAR, upFillRatios);
    break;
    }
    case "overSkin":
    {
    // button fill
    drawRoundRect(
    2, 2, w - 4, h - 4, cr2,
    overFillColors, overFillAlphas,
    verticalGradientMatrix(0, 0, w - 2, h - 2),
    GradientType.LINEAR, overFillRatios);
    break;
    }
    case "downSkin":
    case "selectedDownSkin":
    {
    // button fill
    drawRoundRect(
    2, 2, w - 4, h - 4, cr2,
    downFillColors, downFillAlphas,
    verticalGradientMatrix(0, 0, w - 2, h - 2),
    GradientType.LINEAR, downFillRatios);
    break;
    }
    }
    }
    }
    }



    Step 2. Created a css file where we define the style for our custom button.

    main.css           >>>Download flex tutorial project

    /* CSS file */
    CustomButton
    {
    up-skin: ClassReference("skins.CustomButtonSkin");
    over-skin: ClassReference("skins.CustomButtonSkin");
    down-skin: ClassReference("skins.CustomButtonSkin");
    selected-disabled-skin: ClassReference("skins.CustomButtonSkin");
    selected-over-skin: ClassReference("skins.CustomButtonSkin");
    selected-up-skin: ClassReference("skins.CustomButtonSkin");

    outBorderColors: #eec72c,#ad8a1f;
    inBorderColors: #fffb91,#eed35a;

    cornerRadius: 6;

    upFillAlphas: 1,1,1,1;
    upFillColors: #ffeeb4,#fffb8d,#fff17f,#e9af1f;
    upFillRatios: 0,92,92,255;

    overFillAlphas: 1,1,1,1;
    overFillColors: #ffffff,#fff6ad,#ffed58,#ffcb1a;
    overFillRatios: 0,92,92,255;

    downFillAlphas: 1,1,1,1;
    downFillColors: #ffeeb4,#fffb8d,#fff17f,#e9af1f;
    downFillRatios: 0,106,106,255;

    fontSize: 18;
    color: #7d5a00;

    }


    Step 3. Created a CustomButton class that extends the basic flex Button class so we can bind the "CustomButton style" name to an existing "CustomButton control"

    CustomButton.as

    package controls
    {
    import mx.controls.Button;

    public class CustomButton extends Button
    {
    public function CustomButton()
    {
    super();
    }
    }
    }


    Step 4. Declare the used css file in the application then start using the skinned button

    Application.mxml

    <?xml version="1.0" encoding="utf-8"?>
    <mx:Application
    xmlns:mx = "http://www.adobe.com/2006/mxml"
    layout = "absolute"
    xmlns:controls = "controls.*"
    width = "160"
    height = "60"
    backgroundColor = "#ffffff"
    backgroundGradientColors = "[#ffffff,#ffffff]"
    backgroundGradientAlphas = "[1,1]" viewSourceURL="srcview/index.html">

    <mx:Style source= "styles/main.css"/>

    <controls:CustomButton
    x = "10"
    y = "6"
    width = "140"
    height = "48"
    label = "Click Me!"/>

    </mx:Application>

    Right click inside the sample to view / download custom button project

    And that's all! :)
    I wish you a happy flexing
    ------------------------
    Adrian Pirvulescu