Flex 三态复选框

在周末挤出了一点时间,写了一个三态复选框的组件,单独使用没有价值,不过集成到树之中可以很好的实现三态树,今天上午便把三态树组件也完成了,Flex自定义组件基本无所不能,此组件基于最新的Flex4.6(也支持Apache Flex4.10,我目前已经全面升级到4.10,为了和以后保持一致),废话不表,呆毛如下:

1.首先创建一个类TriStateCheckBox,继承至CheckBox,为了实现复选框的三种状态,我需要设置三个公开的静态常量来表示,用0,1,2来分别表示Unchecked,Checked和Indeterminate三种状态:

 1 public class TriStateCheckBox extends CheckBox

 2 {

 3     public static const Unchecked:int = 0;

 4     public static const Checked:int = 1;

 5     public static const Indeterminate:int = 2;

 6         

 7     public function TriStateCheckBox()

 8     {

 9         super();

10     }

11 }


2.为组件自定义一个checkState属性,用来标识复选框的三种状态,这里需要注意的是当状态处于Checked和Indeterminate时,我们认为复选框的selected=true,因此还需要重写复选框的selected属性,实现两者之间的协调统一:

 1 private var _checkState:int;

 2 [Bindable(event="change")]

 3 [Inspectable(category="General", defaultValue="0")]

 4 public function get checkState():int

 5 {

 6     return _checkState;

 7 }

 8 public function set checkState(value:int):void

 9 {

10     if(value == _checkState)

11         return;

12             

13     _checkState = value;

14     if(_checkState==Indeterminate || _checkState==Checked)

15     {

16         _selected = true;

17     }

18     else

19     {

20         _selected = false;

21     }

22     dispatchEvent(new FlexEvent(FlexEvent.VALUE_COMMIT));

23     invalidateSkinState();

24 }

25         

26 private var _selected:Boolean;

27 [Bindable]

28 [Inspectable(category="General", defaultValue="false")]

29 override public function get selected():Boolean

30 {

31     return _selected;

32 }

33 override public function set selected(value:Boolean):void

34 {

35     if(value == selected && checkState!=Indeterminate)

36     {

37         return;

38     }

39     _selected = value;

40     _checkState = _selected?Checked:Unchecked;

41     dispatchEvent(new FlexEvent(FlexEvent.VALUE_COMMIT));

42     invalidateSkinState();

43 }


3.现在来考虑复选框的外观,我们新建一个皮肤,主机组件设为上面建立的TriStateCheckBox,然后我们就能看到CheckBox的外观代码,大概分成了两个组,一种是没有勾选的状态:up,over,down,disabled,一种是已勾选状态:upAndSelected,overAndSelected,downAndSelected,disabledAndSelected,用来呈现两种状态,现在我就需要再额外增加一种状态的呈现,所以加入四种状态即可:upAndIndeterminated,overAndIndeterminated,downAndIndeterminated,disabledAndIndeterminated:

 1 <s:states>

 2     <s:State name="up" />

 3     <s:State name="over" stateGroups="overStates" />

 4     <s:State name="down" stateGroups="downStates" />

 5     <s:State name="disabled" stateGroups="disabledStates" />

 6     <s:State name="upAndSelected" stateGroups="selectedStates" />

 7     <s:State name="overAndSelected" stateGroups="overStates, selectedStates" />

 8     <s:State name="downAndSelected" stateGroups="downStates, selectedStates" />

 9     <s:State name="disabledAndSelected" stateGroups="disabledStates, selectedStates" />

10     <s:State name="upAndIndeterminated" stateGroups="indeterminatedStates" />

11     <s:State name="overAndIndeterminated" stateGroups="overStates, indeterminatedStates" />

12     <s:State name="downAndIndeterminated" stateGroups="downStates, indeterminatedStates" />

13     <s:State name="disabledAndIndeterminated" stateGroups="disabledStates, indeterminatedStates" />

14 </s:states>


4.好了,我现在要重写组件的状态切换逻辑,以便使组件根据三种状态来切换对应的state:

 1 override protected function getCurrentSkinState():String

 2 {

 3     var state:String = super.getCurrentSkinState();

 4     if(checkState==Indeterminate)

 5     {

 6         switch(state)

 7         {

 8             case "up":

 9             case "upAndSelected":

10             {

11                 state = "upAndIndeterminated";

12                 break;

13             }

14             case "over":

15             case "overAndSelected":

16             {

17                 state = "overAndIndeterminated";

18                 break;

19             }

20             case "down":

21             case "downAndSelected":

22             {

23                 state = "downAndIndeterminated";

24                 break;

25             }

26             case "disabled":

27             case "disabledAndSelected":

28             {

29                 state = "disabledAndIndeterminated";

30                 break;

31             }

32         }

33     }

34     return state;

35 }


5.最后,只需要在外观代码中加入我想要的第三种状态的外观即可,我个人还是比较喜欢实心方块的外观,因此我打算直接绘制一个Rect填充,此处是可以自行定义的,比如你喜欢画个空心园来表示第三状态,或者画个灰色的勾,都是可以的,思想没有边界,Flex的强大只有懂的人才能体会:

1 <s:Rect left="2" top="2" right="2" bottom="2" includeIn="indeterminatedStates">

2     <s:fill>

3         <s:SolidColor id="indeterminatedMarkFill" color="0" alpha="0.8" />

4     </s:fill>

5 </s:Rect>

 

你可能感兴趣的:(Flex)