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>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM