如何使用AS3动态更改XML按钮的颜色?

时间:2013-10-03 14:57:12

标签: xml flex button colors gradient

我已经在这几天苦苦挣扎了,这感觉很荒谬。这不是什么新鲜事,我似乎无法在任何地方找到答案。我有三个文件,所以这里有一些关于它们如何设置的示例片段。

Viewer.mxml

<fx:Script>
<![CDATA[
  function changeColorState()
  {
    if(some condition is true)
    {
      myButton.colorState = TessaButton.PINK_COLORSTATE;
    }
    else
    {
      myButton.colorState = TessaButton.GRAY_COLORSTATE;
    }
  myButton.skin.setCurrentState('up');
  }
]]>
</fx:Script>
<s:VGroup>
  <TessaButton id="myButton"
               labelText="Example Button"
               click="doSomething(event)"
               skinClass="ButtonSkin" />
</s:VGroup>

TessaButton.mxml

<fx:Script>
<![CDATA[
  public static const PINK_COLORSTATE:String = 'Pink';
  public static const GRAY_COLORSTATE:String = 'Gray';

  public var colorState:String = PINK_COLORSTATE;//Default setting
]]>
</fx:Script>

ButtonSkin.mxml

<s:states>
  <s:State name="up" enterState="enterStateHandler(event)"/>
  <s:State name="down" />
  <s:State name="over" />
  <s:State name="disabled />
</s:states>

<fx:Script>
<![CDATA[
  //Pretend that these are all shades and tints of pink or gray, too lazy to make up examples
  public static const GE1_PINK_UP:uint = 0xffa2f7;
  public static const GE1_PINK_OVER:uint = 0xffa2f7;
  public static const GE1_PINK_DOWN:uint = 0xffa2f7;
  public static const GE2_PINK_UP:uint = 0xffa2f7;
  public static const GE2_PINK_OVER:uint = 0xffa2f7;
  public static const GE2_PINK_DOWN:uint = 0xffa2f7;

  public static const GE1_GRAY_UP:uint = 0xffa2f7;
  public static const GE1_GRAY_OVER:uint = 0xffa2f7;
  public static const GE1_GRAY_DOWN:uint = 0xffa2f7;
  public static const GE2_GRAY_UP:uint = 0xffa2f7;
  public static const GE2_GRAY_OVER:uint = 0xffa2f7;
  public static const GE2_GRAY_DOWN:uint = 0xffa2f7;

  private var fillColor1_up:uint = GE1_PINK_UP;//Default setting is pink
  private var fillColor1_over:uint = GE1_PINK_OVER;
  private var fillColor1_down:uint = GE1_PINK_DOWN;
  private var fillColor2_up:uint = GE2_PINK_UP;
  private var fillColor2_over:uint = GE2_PINK_OVER;
  private var fillColor2_down:uint = GE2_PINK_DOWN;

  private function enterStateHandler(e:FlexEvent):void
  {
    switch((hostComponent as ButtonProperties).colorState)
    {
      case 'Pink':
        fillColor1_up = GE1_PINK_UP;
        //And the rest set to the pink colors
        break;
      case 'Gray':
        fillColor1_up = GE1_GRAY_UP;
        //And the rest set to the gray colors
        break;
    }
]]>
</fx:Script>
<s:Rect id="fill">
  <s:fill>
    <s:LinearGradient rotation="90">
      <s:GradientEntry color.up="{fillColor1_up}"
                       color.over="{fillColor1_over}"
                       color.down="{fillColor1_down}" />
      <s:GradientEntry color.up="{fillColor2_up}"
                       color.over="{fillColor2_over}"
                       color.down="{fillColor2_down}" />
    </s:LinearGradient>
  </s:fill>
</s:Rect>

我的印象是,当fillColor变量的值发生变化时,渐变条目中的这些颜色将动态变化。在这种情况下,当按钮上的状态发生变化为'up'时,这些值会发生变化。默认情况下,这些按钮将显示为粉红色。如果我有条件,则colorState变量为灰色,因此按钮应为灰色。但是,在运行它时,我在enterStateHandler中看到的跟踪语句,我看到它们正在我需要的灰色和粉红色之间正确地改变,但它们仍然是视觉上粉红色的。我不明白为什么。如果有人能指出我正确的方向,或者有人可以说明为什么这不起作用,请告诉我。谢谢!

1 个答案:

答案 0 :(得分:0)

您需要将可变颜色变量标记为&#39; Bindable&#39;。这告诉Flex要密切注意这些值,当它们发生变化时,要更新使用它们的任何其他内容(例如渐变)。

所以你需要:

[Bindable] private var fillColor1_up:uint = GE1_PINK_UP;
[Bindable] private var fillColor1_over:uint = GE1_PINK_OVER;
[Bindable] private var fillColor1_down:uint = GE1_PINK_DOWN;
[Bindable] private var fillColor2_up:uint = GE2_PINK_UP;
[Bindable] private var fillColor2_over:uint = GE2_PINK_OVER;
[Bindable] private var fillColor2_down:uint = GE2_PINK_DOWN;