Flex自定義組件開發之日周月日期選擇日歷控件


 

        使用過DateField的我們都知道,DateField 控件是用於顯示日期的文本字段,字段右側帶有日歷圖標。當用戶在控件邊框內的任一位置單擊時,將彈出一個 DateChooser 控件,顯示當月的所有日期。如果未選擇日期,則該文本字段為空白,並且 DateChooser 控件中將顯示當前日期的月份。當 DateChooser 控件處於打開狀態時,用戶可以在各個月份和年份之間滾動,並選擇某個日期。選擇日期后,DateChooser 控件關閉,文本字段將顯示所選的日期。而在我們的業務過程中,很多時候我們需要選擇的日期不僅僅是某天,可能還需要的是某些時間段,比如說一周,一個月,這是DateField就滿足不了我們的需求,它提供的只是對某個日期的選擇。這時候就需要我們進行自定義組件的開發了。而這個突破口就在DateChooser ,DateChooser控件顯示月份名稱、年份名稱,並顯示包含當月的所有日期的網格(每列標有對應的星期日期)。用戶可以選擇一個日期、某個日期范圍或者多個日期。此控件包含前進和后退箭頭按鈕,用於改變年份和月份。您可以允許用戶選擇多個日期,禁止選擇特定日期和只限於顯示某個日期范圍。DateChooser的這些特性滿足了我們的需求,因此我們可以利用它進行我們所需要組件的開發。下面先看一小效果實現圖(鼠標點擊):
 
 我們可以看下包結構:
首先是對控件的主體DateWeekMouthDateField.mxml進行分析,代碼如下
<?xml version="1.0" encoding="utf-8"?>
<s:BorderContainer xmlns:fx="http://ns.adobe.com/mxml/2009" 
                   xmlns:s="library://ns.adobe.com/flex/spark" 
                   xmlns:mx="library://ns.adobe.com/flex/mx" 
                   width="100%" height="100%" backgroundAlpha="0"
                   borderVisible="false"
                   buttonMode="true" useHandCursor="true"
                   creationComplete="init();"
                   click="popUpButton.open();">
    
    <fx:Style source="css/tabNavigator.css"/> 
    <fx:Script>
        <![CDATA[
            import DateField.component.DateChoosers;
            import DateField.event.DateFieldChooseEvent;
            
            [Embed(source="DateField/images/leftIcon.png")]
            private var leftIcon:Class;
            [Embed(source="DateField/images/rightIcon.png")]
            private var rightIcon:Class;
            public var dateChoosers:DateChoosers = new DateChoosers();;
            /**
             * 初始化導航菜單組
             * */
            private function init():void
            {    
                
                var date:Date = new Date();
                var dateString:String = "" + date.getFullYear() + "-" + (date.getMonth()+1) + "-"
                    + date.getDate();
                dateSlectLabel.text = dateString;
//                dateChoosers.dateLabel = ["日","周","月","年"];
//                dateChoosers.dateLabel = ["日","周"];
                popUpButton.popUp = dateChoosers;
                
                /* open it just for initialize. */
                popUpButton.open();
                popUpButton.close();
                dateChoosers.addEventListener(DateFieldChooseEvent.DATE_SELECTED,dateSelectedHandler);
            }
            
            protected function dateSelectedHandler(event:DateFieldChooseEvent):void
            {
                // TODO Auto-generated method stub
                dateSlectLabel.text = event.vEventResult;
                popUpButton.label = event.vEventResult;
                popUpButton.close();
            }
            
        ]]>
    </fx:Script>
    
    <fx:Declarations>
        <!-- 將非可視元素(例如服務、值對象)放在此處 -->
    </fx:Declarations>
    <s:layout>
        <s:VerticalLayout />
    </s:layout>
    <s:BorderContainer id="imgLabel" width="100%" height="100%" borderVisible="false" backgroundAlpha="0">
        <s:Image id="leftImg" x="0" source="{leftIcon}" />
        <s:Label id="dateSlectLabel" x="15" y="3"
                 text="2013-7-6"
                 paddingLeft="5" paddingRight="5"
                 verticalAlign="middle" maxDisplayedLines="1" textAlign="center" fontFamily="微軟雅黑" />
        <s:Image id="rightImg" x="{dateSlectLabel.width + 15}" source="{rightIcon}" />
    </s:BorderContainer>
    <mx:PopUpButton id="popUpButton"
                    label="日期選擇" visible="false" chromeColor="0xE8FFE2"
                    alpha="0.8" buttonMode="true"  width="0" height="0" open="dateChoosers.x -= 25;"
                    openAlways="true" useHandCursor="true">
    </mx:PopUpButton>
</s:BorderContainer>

 

DateWeekMouthDateField 的主體是一個BorderContainer,它包含了一個顯示標簽Label和2個用來外觀顯示Image以及一個PopUpButton,看下Script里面的代碼我們就可以發現它彈出的是dateChoosers。下面我們來看下dateChoosers,源碼如下:
package DateField.component
{
    import DateField.event.DateFieldChooseEvent;
    
    import mx.containers.TabNavigator;
    import mx.containers.VBox;
    import mx.controls.DateChooser;
    import mx.controls.List;
    import mx.core.ScrollPolicy;
    import mx.events.CalendarLayoutChangeEvent;
    import mx.events.ListEvent;
    
    import spark.components.BorderContainer;
    
    /**
     * 日周月年日期選擇控件,包含了日日期選擇器,周日期選擇器,月份選擇器和年份選擇器 
     * @author jackyWHJ
     * @date 2013-7-30
     * @version 1.0
     * 
     */
    public class DateChoosers extends BorderContainer
    {
        //-----------------------------------------------------
        //    控件需要從外部接收參數的屬性定義 start
        //-----------------------------------------------------
        /**
         * 啟用年份導航。如果為 true,則顯示的年份右側會出現向上和向下按鈕。
         * 您可以使用這些按鈕更改當前年份。
         * 在采用年份顯示在月份之前的日期格式的區域設置中,這些按鈕將顯示在年份的左側。 
         * @default true 
         */
        private var _yearNavigationEnabled:Boolean = true;
        
        /**
         * DateChooser 控件的工作日名稱。
         * 更改此屬性可更改 DateChooser 控件的日期標簽。
         * 星期日為第一天(在索引為 0 處)。
         * 一周中其余的天按照正常的順序命名。
         * @default ["日", "一", "二", "三", "四", "五", "六"]
         */
        private var _dayNames:Array = ["日", "一", "二", "三", "四", "五", "六"];
        
        /**
         * 顯示在 DateChooser 控件頂部的月份名稱。
         * 將 monthSymbol 屬性追加到由 monthNames 屬性指定的值末尾,該屬性這在語言(如日語)中很有用。
         * @default ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月","十二月"]
         */
        private var _monthNames:Array = ["一月", "二月", "三月", "四月", "五月",
            "六月", "七月", "八月", "九月", "十月", "十一月","十二月"];
        
        /**
         * 控件中可選的最后一個年份。
         * @default 2020 
         */
        private var _maxYear:uint = 2020; 
        
        /**
         * 控件中可選的第一個年份。
         * @default 2009
         */
        private var _minYear:uint = 2009; 
        
        /**
         * 日期控件的寬度 
         * @default 210
         */
        private var _chooserWidth:Number = 210;
        
        /**
         * 日期控件的高度
         * @default 200
         */
        private var _chooserHeight:Number = 200;
        
        /**
         * 如果為 true,則指定在 DateChooser 控件中允許選擇不連續的日期。
         * 僅當 allowMultipleSelection 屬性設置為 true 時,此屬性才起作用。
         * 設置此屬性可更改 DateChooser 控件的外觀。 默認值為 false。
         */
        private var _allowDisjointSelection:Boolean = false;
        
        /**
         * 如果為 true,則指定在 DateChooser 控件中允許選擇多個日期。
         * 設置此屬性可更改 DateChooser 控件的外觀。 默認值true。
         */
        private var _allowMultipleSelection:Boolean = true;
        
        /**
         * 每周中要禁用的日期。每月中除指定日期外,所有日期都被禁用。
         * 此屬性可更改 DateChooser 控件的外觀。
         * 此數組中的元素可使用介於 0(星期日)到 6(星期六)之間的值。例如,如果設置值 [ 0, 6 ],將禁用星期日和星期六。 
         * 默認值為 []。
         * */
        private var _disabledDays:Array = [];
        
        /**
         * 禁用一天或多天。 此屬性接受對象 Array 作為參數。
         * 此數組中的所有對象都是 Date 對象,用於指定要禁用的各個日期;也可以是一個包含 rangeStart 和(或)rangeEnd 屬性的對象。
         * 這些屬性的值描述了日期范圍的邊界。如果忽略其中任一屬性,則認為在該方向上無范圍限制。
         * 如果僅指定 rangeStart,則將禁用指定日期之后的所有日期(包括 rangeStart 日期)。
         * 如果僅指定 rangeEnd,則將禁用指定日期之前的所有日期(包括 rangeEnd 日期)。
         * 要禁用單個日期,請使用一個 Date 對象指定 Array 中的某個日期。時間值(如果存在)將以 Date 對象為零值,依次遞增。
         * 以下示例將禁用下列日期:2006 年 1 月 11 日,從 2006 年 1 月 23 至同年 2 月 10 日,以及 2006 年 3 月 1 日及后續所有日期。
         * disabledRanges="{[ new Date(2006,0,11), {rangeStart: new Date(2006,0,23), 
         * rangeEnd: new Date(2006,1,10)}, {rangeStart: new Date(2006,2,1)} ]}"
         * 默認值為 []。
         */
        private var _disabledRanges:Array = [];
        
        /**
         * 一個數字,該數字代表顯示在 DateChooser 控件第一列中的一周中的日期。
         * 該值必須介於 0 到 6 之間,其中 0 對應星期日,這是 dayNames Array 中的第一個元素。 
         * 設置此屬性將更改日期列的順序。例如,將其設置為 1 可將星期一設置為該控件中的第一列。
         * 默認值為 0 (Sunday)。
         */
        private var _firstDayOfWeek:Object = 0;
        
        /**
         * 此屬性將追加到由 monthNames 屬性指定的值的末尾,用於定義顯示在 DateChooser 控件頂部的月份名稱。
         * 有些語言(如日語)會在月份名稱后使用額外的符號。 默認值為 ""。
         */
        private var _monthSymbol:String = "";
        
        /**
         * 日期范圍,可從中選擇日期。例如,可以選擇 04-12-2006 和 04-12-2007 之間的日期,而超出此范圍的日期將被禁用。 
         * 此屬性接受 Object 作為參數。該 Object 包含 Date 類型的兩個屬性:rangeStart 和 rangeEnd。
         * 如果僅指定了 rangeStart,則在此指定日期之后的所有日期都可用。如果僅指定了 rangeEnd,則在此指定日期之前的所有日期都可用。
         * 要僅在 DateChooser 控件中使用一個日期,可以直接傳遞一個 Date 對象。時間值(如果存在)將以 Date 對象為零值,依次遞增。
         * 以下示例僅啟用 2006 年 1 月 1 日到 2006 年 6 月 30 日的范圍。1 月之前和 6 月之后的月份不會出現在 DateChooser 中。
         * selectableRange="{{rangeStart : new Date(2006,0,1), rangeEnd : new Date(2006,5,30)}}"
         * 默認值為 null
         */
        private var _selectableRange:Object;
        
        /**
         * 在 DateChooser 控件中選擇的日期。如果傳入的 Date 對象包含任何時間值,則它們將被清零。 
         * 在控件中選擇當前所選日期時按住 Ctrl 鍵可取消對該日期的選擇,將 selectedDate 屬性設置為 null,然后分派 change 事件。
         * 默認值為 null。
         */
        private var _selectedDate:Date = null;
        
        /**
         * 如果為 true,則指定在 DateChooser 控件中加亮顯示今天。設置此屬性可更改 DateChooser 控件的外觀。 
         * 默認值為 true。
         */
        private var _showToday:Boolean = true;
        
        /**
         * 此屬性附加在 DateChooser 控件頂部顯示的年份末尾。有些語言(如日語)會在年份后添加符號。 
         * 默認值為 ""。
         */
        private var _yearSymbol:String = "";
        
        /**
         * 日期選擇器標簽 ,日期選擇器就是由這個標簽來生成的。
         * 總共有["日","周","月","年"]4個日期標簽,如果該值設置為["日","周"]的話,那就只有日周2個日期選擇器。
         */
        private var _dateLabel:Array = ["日","周","月"];
        
        /**
         * 月份日期選擇器日期范圍需要在當前月份推前的月份數,比如現在是2013年7月,
         * 那么默認值48則表示從該日期往前推48個月,也就是說,目前的日期選擇最前可以是2009年7月 
         */
        private var _beforeMonthCount:uint = 48;
        
        /**
         * 月份日期選擇器日期范圍需要在當前月份推后的月份數,比如現在是2013年7月,
         * 值為2則表示從該日期往后推2個月,也就是說,日期選擇最后可以是2013年9月 
         */
        private var _afterMonthCount:uint = 0;
        
        /**
         * 年份日期選擇器日期范圍需要在當前月份推前的月份數,比如現在是2013年
         * 那么默認值4則表示從該日期往前推4年,也就是說,目前的日期選擇最前可以是2009年 
         */
        private var _beforeYearCount:uint = 4;
        
        /**
         * 年份日期選擇器日期范圍需要在當前年份推后的月份數,比如現在是2013年,
         * 值為2則表示從該日期往后推2年,也就是說,日期選擇最后可以是2015年。 
         */
        private var _afterYearCount:uint = 0;
        
        /**
         * 當前默認是選擇哪個日期選擇器,默認是0,日日期選擇器
         */
        private var _selectedIndex:int = 0;
        
        //-----------------------------------------------------
        //    控件需要從外部接收參數的屬性定義 end
        //-----------------------------------------------------
        
        //-----------------------------------------------------
        //    控件內部屬性定義 start
        //-----------------------------------------------------
        /**
         * 月份選擇下拉列表 
         */
        private var monthList:List;
        
        /**
         * 年份選擇下拉列表 
         */
        private var yearList:List;
        
        /**
         * 月份選擇控件數據源數據
         */
        private var dateArray:Array;
        
        /**
         * 日日期選擇器
         */
        private var dateChooser1:DateChooser;
        
        /**
         * 周日期選擇器
         */
        private var dateChooser2:DateChooser;
        
        /**
         * MX TabNavigator 容器通過包括一個用於在其子容器間導航的 TabBar 容器來擴展 MX ViewStack 容器。  
         */
        private var tabNavigator:TabNavigator;
        
        /**
         * TabNavigator的日日期選擇器子容器
         */
        private var dateField:VBox;
        
        /**
         * TabNavigator的周日期選擇器子容器
         */
        private var weekField:VBox;
        
        /**
         * TabNavigator的月日期選擇器子容器
         */
        private var monthField:VBox;
        
        /**
         * TabNavigator的年日期選擇器子容器
         */
        private var yearField:VBox;
        //-----------------------------------------------------
        //    控件內部屬性定義 end
        //-----------------------------------------------------
        /**
         * 構造函數,初始化並添加子容器
         * 
         */
        public function DateChoosers()
        {
            //TODO: implement function
            super();
            this.width = chooserWidth;
            this.height = chooserHeight;
            
        }
 
        override protected function createChildren():void
        {
            //初始化tabNavigator
            if(tabNavigator == null)
            {
                tabNavigator = new TabNavigator();
                tabNavigator.styleName = "TabNavigator";
//                tabNavigator.percentWidth = 100;
                tabNavigator.width = chooserWidth + 1;
                tabNavigator.percentHeight = 100;
                tabNavigator.x = -1;
                this.addElement(tabNavigator);
            }
            
            
            //設置 tabNavigator 的tabWidth 長度
            if (dateLabel != null && dateLabel.length >0)
            {
                tabNavigator.setStyle("tabWidth",chooserWidth/dateLabel.length + 1);
            }
            
            //dateLabel 的長度大於0,也是就是dateLabel至少有1個元素,則添加日日期選擇器容器
            if(dateLabel.length > 0 && dateField == null)
            {
                //初始化dateField
                dateField = new VBox();
                dateField.label = dateLabel[0];
                dateField.percentWidth = 100; 
                dateField.percentHeight = 100;
                tabNavigator.addElement(dateField);
            }
            
            //dateLabel 的長度大於1,也是就是dateLabel至少有2個元素,則添加周日期選擇器容器
            if(dateLabel.length > 1 && weekField == null)
            {
                //初始化weekField
                weekField = new VBox();
                weekField.label = dateLabel[1];
                weekField.percentWidth = 100; 
                weekField.percentHeight = 100;
                tabNavigator.addElement(weekField);
            }
            
            //dateLabel 的長度大於2,也是就是dateLabel至少有3個元素,則添加月日期選擇器容器
            if(dateLabel.length > 2 && monthField == null)
            {
                //初始化monthField
                monthField = new VBox();
                monthField.label = dateLabel[2];
                monthField.percentWidth = 100; 
                monthField.percentHeight = 100;
                monthField.verticalScrollPolicy = ScrollPolicy.OFF ;
                monthField.horizontalScrollPolicy = ScrollPolicy.OFF;
                tabNavigator.addElement(monthField);
            }
            
            //dateLabel 的長度大於3,也是就是dateLabel至少有4個元素,則添加年日期選擇器容器
            if(dateLabel.length > 3 && yearField == null)
            {
                //初始化yearField
                yearField = new VBox();
                yearField.label = dateLabel[3];
                yearField.percentWidth = 100; 
                yearField.percentHeight = 100;
                yearField.verticalScrollPolicy = ScrollPolicy.OFF ;
                yearField.horizontalScrollPolicy = ScrollPolicy.OFF;
                tabNavigator.addElement(yearField);
            }
            
            tabNavigator.selectedIndex = selectedIndex;
            
            this.init();
        }
        
        /**
         * 初始化日周月各日期選擇器,並綁定數據源,添加監聽事件 
         * 
         */
        private function init():void 
        {
            if(dateField != null)
            {
                //初始化day日期選擇器的
                dateChooser1 = new DateChooser();
                dateChooser1.percentWidth = 100; 
                dateChooser1.percentHeight = 100; 
                dateChooser1.yearNavigationEnabled = this.yearNavigationEnabled;
                dateChooser1.dayNames = this.dayNames;
                dateChooser1.monthNames = this.monthNames;
                dateChooser1.maxYear = this.maxYear; 
                dateChooser1.minYear = this.minYear; 
                dateChooser1.allowDisjointSelection = allowDisjointSelection;
                dateChooser1.allowMultipleSelection = allowMultipleSelection;
                dateChooser1.disabledDays = disabledDays;
                dateChooser1.disabledRanges = disabledRanges;
                dateChooser1.firstDayOfWeek = firstDayOfWeek;
                dateChooser1.selectedDate = selectedDate;
                dateChooser1.monthSymbol = monthSymbol;
                dateChooser1.selectableRange = selectableRange;
                dateChooser1.showToday = showToday;
                dateChooser1.yearSymbol = yearSymbol;
                dateChooser1.x = -1;
                dateChooser1.styleName = "DateChooser";
                dateChooser1.addEventListener(CalendarLayoutChangeEvent.CHANGE,dateChooser1_changeHandler);
                dateField.addElement(dateChooser1);
            }
            
            if(weekField != null)
            {
                //初始化week日期選擇器
                dateChooser2 = new DateChooser();
                dateChooser2.percentWidth = 100; 
                dateChooser2.percentHeight = 100; 
                dateChooser2.yearNavigationEnabled = this.yearNavigationEnabled;
                dateChooser2.dayNames = this.dayNames;
                dateChooser2.monthNames = this.monthNames;
                dateChooser2.maxYear = this.maxYear; 
                dateChooser2.minYear = this.minYear; 
                dateChooser2.allowDisjointSelection = this.allowDisjointSelection;
                dateChooser2.allowMultipleSelection = this.allowMultipleSelection;
                dateChooser2.disabledDays = disabledDays;
                dateChooser2.disabledRanges = disabledRanges;
                dateChooser2.firstDayOfWeek = firstDayOfWeek;
                dateChooser2.monthSymbol = monthSymbol;
                dateChooser2.yearSymbol = yearSymbol;
                dateChooser2.x = -1;
                dateChooser2.styleName = "DateChooser";
                dateChooser2.addEventListener(CalendarLayoutChangeEvent.CHANGE,dateChooser2_changeHandler);
                weekField.addElement(dateChooser2);
                
                //初始化week日期選擇器的選擇數據
                var currentDate:Date;
                //如果已經設置了選擇的日期,則當前日期安裝選擇日期來
                if(selectedDate)
                {
                    currentDate = selectedDate;
                }
                else
                {
                    currentDate = new Date();
                }
                var date1:Date = new Date(currentDate.getTime());
                var date2:Date = new Date(currentDate.getTime());
                var distinceDay:Number = currentDate.getDay();
                if(distinceDay > 0)
                {
                    date1.date -= distinceDay - 1;
                    date2.date = currentDate.date + (7 - distinceDay);
                }
                else
                {
                    date1.date -= distinceDay - 6;
                }
                //                trace(DateChooser(event.target).selectedDate.getUTCDay ());
                dateChooser2.selectedRanges = [{rangeStart: date1, rangeEnd: date2}];
                
            }
            
            var currentYear:uint;
            var beforeYear:uint;
            var afterYear:uint;
            
            //初始化月日期選擇器
            var rowCount:int = 0;
            if(monthField != null)
            {
                monthList = new List();
                rowCount = 0;
                dateArray = new Array();
                //根據當前日期和要推前的月份數計算最前日期應該是那一年那一月
                currentYear = currentDate.getFullYear();
                var currentMonth:uint = currentDate.getMonth() + 1;
                beforeYear = currentYear - uint(this.beforeMonthCount / 12);
                var beforeMonth:int = currentMonth - uint(this.beforeMonthCount % 12);
                //如果減下來的日期已經超過這一年的日期,則月份從前一年開始算
                if(beforeMonth <= 0)
                {
                    -- beforeYear;
                    beforeMonth = 12 + beforeMonth;
                }
                afterYear = currentYear + uint(this.afterMonthCount / 12);
                var afterMonth:int = currentMonth + uint(this.afterMonthCount % 12);
                //如果加下來的日期已經超過這一年的日期,則月份從后一年開始算
                if(afterMonth > 12)
                {
                    ++ afterYear;
                    afterMonth = afterMonth - 12;
                }
                //初始化月日期選擇器的數據源
                for (var i:int = afterYear; i >= beforeYear; i--)
                {
                    for (var j:int = 12 ;j >0 ; j--)
                    {
                        //最后日期后的略過
                        if (i == afterYear && j > afterMonth)
                        {
                            continue;
                        }
                        //最前日期前的直接終止
                        if (i == beforeYear && j < beforeMonth)
                        {
                            break;
                        }
                        var dateString:String = "" + i + "年" + j + "月";
                        rowCount = dateArray.push(dateString);
                        //如果設置了選中日期,則默認選擇日期按照選中日期來,否則,默認選中日期為當前日期
                        if(this.selectedDate)
                        {
                            if (i == this.selectedDate.getFullYear() && j == (this.selectedDate.getMonth() + 1))
                            {
                                monthList.selectedIndex = rowCount - 1;
                            }
                        }
                        else
                        {
                            if (i == currentYear && j == currentMonth)
                            {
                                monthList.selectedIndex = rowCount - 1;
                            }
                        }
                        
                    }
                }
                
                monthList.dataProvider = dateArray;
                monthField.addElement(monthList);
                monthList.percentWidth = 100;
                monthList.addEventListener(ListEvent.ITEM_CLICK, itemClickHandler);
            }
            //初始化年日期選擇器
            if(yearField != null)
            {
                yearList = new List();
                rowCount = 0;
                dateArray = new Array();
                currentYear = currentDate.getFullYear();
                beforeYear = currentYear - this.beforeYearCount;
                afterYear = currentYear + this.afterYearCount;
                //初始化年日期選擇器的數據源
                for (var k:int = afterYear; k >= beforeYear; k--)
                {
                    var yearString:String = "" + k + "年";
                    rowCount = dateArray.push(yearString);
                    //如果設置了選中日期,則默認選擇日期按照選中日期來,否則,默認選中日期為當前日期
                    if(this.selectedDate)
                    {
                        if (k == this.selectedDate.getFullYear())
                        {
                            yearList.selectedIndex = rowCount - 1;
                        }
                    }
                    else
                    {
                        if (k == currentYear)
                        {
                            yearList.selectedIndex = rowCount - 1;
                        }
                    }
                }
                
                yearList.dataProvider = dateArray;
                yearField.addElement(yearList);
                yearList.percentWidth = 100;
                yearList.addEventListener(ListEvent.ITEM_CLICK, yearItemClickHandler);
            }
            
        }
        
        /**
         * 年日期選擇器的選擇點擊監聽事件 
         * @param evt
         * 
         */
        protected function yearItemClickHandler(event:ListEvent):void
        {
            // TODO Auto-generated method stub
            yearList.selectedIndex = event.rowIndex;
            this.dispatchEvent(new DateFieldChooseEvent(DateFieldChooseEvent.DATE_SELECTED, 
                yearList.selectedItem));
        }
        
        /**
         * 月日期選擇器的選擇點擊監聽事件 
         * @param evt
         * 
         */
        protected function itemClickHandler(evt:ListEvent):void {
            trace("evt.index:" + monthList.selectedItem);
            monthList.selectedIndex = evt.rowIndex;
            this.dispatchEvent(new DateFieldChooseEvent(DateFieldChooseEvent.DATE_SELECTED, 
                monthList.selectedItem));
        }
        
        /**
         * 周 日期選擇器的選擇點擊監聽事件 
         * @param event
         * 
         */
        protected function dateChooser2_changeHandler(event:CalendarLayoutChangeEvent):void
        {
            // 獲取當前選中的日期,再根據當前日期是周幾取得這星期的第一天和最后一天
            var currentDate:Date = DateChooser(event.target).selectedDate;
//            trace(DateChooser(event.target).selectedDate);
            var date1:Date = new Date(currentDate.getTime());
            var date2:Date = new Date(currentDate.getTime());
            var distinceDay:Number = currentDate.getDay();
            if(distinceDay > 0)
            {
                date1.date -= distinceDay - 1;
                date2.date = currentDate.date + (7 - distinceDay);
            }
            else
            {
                date1.date -= distinceDay - 6;
            }
            dateChooser2.selectedRanges = [{rangeStart: date1, rangeEnd: date2}];
            var dateString:String = "" + date1.getFullYear() + "-" + (date1.getMonth()+1) + "-"
                + date1.getDate() + "~" + date2.getFullYear() + "-" + (date2.getMonth()+1) + "-"
                + date2.getDate();
            trace(dateString);
            this.dispatchEvent(new DateFieldChooseEvent(DateFieldChooseEvent.DATE_SELECTED, 
                dateString));
        }
        
        /**
         * 日日期選擇器的選擇點擊監聽事件  
         * @param event
         * 
         */
        protected function dateChooser1_changeHandler(event:CalendarLayoutChangeEvent):void
        {
            var date:Date = DateChooser(event.target).selectedDate;
            var ob:Object = DateChooser(event.target).selectedRanges;
            var dateString:String;
//            trace(ob);
            if(ob !=  null)
            {
                var date1:Date = ob[0].rangeStart;
                var date2:Date = ob[0].rangeEnd;
                if(date1.getFullYear() == date2.getFullYear() && date1.getMonth() == date2.getMonth() 
                    && date1.getDate() == date2.getDate())
                {
                    dateString = "" + date.getFullYear() + "-" + (date.getMonth()+1) + "-"
                        + date.getDate();
                }
                else
                {
                    dateString = "" + date1.getFullYear() + "-" + (date1.getMonth()+1) + "-"
                        + date1.getDate() + "~" + date2.getFullYear() + "-" + (date2.getMonth()+1) + "-"
                        + date2.getDate();
                }
            }
            else
            {
                dateString = "" + date.getFullYear() + "-" + (date.getMonth()+1) + "-"
                    + date.getDate();
            }
            
            trace(dateString);
            this.dispatchEvent(new DateFieldChooseEvent(DateFieldChooseEvent.DATE_SELECTED, 
                dateString));
        }
        
        /**
         * 啟用年份導航。如果為 true,則顯示的年份右側會出現向上和向下按鈕。
         * 您可以使用這些按鈕更改當前年份。
         * 在采用年份顯示在月份之前的日期格式的區域設置中,這些按鈕將顯示在年份的左側。 
         */
        public function get yearNavigationEnabled():Boolean
        {
            return _yearNavigationEnabled;
        }
 
        /**
         * @private
         */
        public function set yearNavigationEnabled(value:Boolean):void
        {
            _yearNavigationEnabled = value;
        }
 
        /**
         * DateChooser 控件的工作日名稱。
         * 更改此屬性可更改 DateChooser 控件的日期標簽。
         * 星期日為第一天(在索引為 0 處)。
         * 一周中其余的天按照正常的順序命名。
         * @default ["日", "一", "二", "三", "四", "五", "六"]
         */
        public function get dayNames():Array
        {
            return _dayNames;
        }
 
        /**
         * @private
         */
        public function set dayNames(value:Array):void
        {
            _dayNames = value;
        }
 
        /**
         * 顯示在 DateChooser 控件頂部的月份名稱。
         * 將 monthSymbol 屬性追加到由 monthNames 屬性指定的值末尾,該屬性這在語言(如日語)中很有用。
         * @default ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月","十二月"]
         */
        public function get monthNames():Array
        {
            return _monthNames;
        }
 
        /**
         * @private
         */
        public function set monthNames(value:Array):void
        {
            _monthNames = value;
        }
 
        /**
         * 控件中可選的最后一個年份。
         * @default 2020 
         */
        public function get maxYear():uint
        {
            return _maxYear;
        }
 
        /**
         * @private
         */
        public function set maxYear(value:uint):void
        {
            _maxYear = value;
        }
 
        /**
         * 控件中可選的第一個年份。
         * @default 2009
         */
        public function get minYear():uint
        {
            return _minYear;
        }
 
        /**
         * @private
         */
        public function set minYear(value:uint):void
        {
            _minYear = value;
        }
 
        /**
         * 日期控件的寬度 
         * @default 210
         */
        public function get chooserWidth():Number
        {
            return _chooserWidth;
        }
 
        /**
         * @private
         */
        public function set chooserWidth(value:Number):void
        {
            _chooserWidth = value;
        }
 
        /**
         * 日期控件的高度
         * @default 200
         */
        public function get chooserHeight():Number
        {
            return _chooserHeight;
        }
 
        /**
         * @private
         */
        public function set chooserHeight(value:Number):void
        {
            _chooserHeight = value;
        }
        
        /**
         * 日期選擇器標簽 ,日期選擇器就是由這個標簽來生成的。
         * 總共有["日","周","月","年"]4個日期標簽,如果該值設置為["日","周"]的話,那就只有日周2個日期選擇器。
         */
        public function get dateLabel():Array 
        {
            return _dateLabel;
        }
 
        /**
         * @private
         */
        public function set dateLabel(value:Array):void
        {
            _dateLabel = value;
        }
 
        /**
         * 如果為 true,則指定在 DateChooser 控件中允許選擇不連續的日期。
         * 僅當 allowMultipleSelection 屬性設置為 true 時,此屬性才起作用。
         * 設置此屬性可更改 DateChooser 控件的外觀。 默認值為 false。
         */
        public function get allowDisjointSelection():Boolean
        {
            return _allowDisjointSelection;
        }
 
        /**
         * @private
         */
        public function set allowDisjointSelection(value:Boolean):void
        {
            _allowDisjointSelection = value;
        }
 
        /**
         * 如果為 true,則指定在 DateChooser 控件中允許選擇多個日期。
         * 設置此屬性可更改 DateChooser 控件的外觀。 默認值true。
         */
        public function get allowMultipleSelection():Boolean
        {
            return _allowMultipleSelection;
        }
 
        /**
         * @private
         */
        public function set allowMultipleSelection(value:Boolean):void
        {
            _allowMultipleSelection = value;
        }
 
        /**
         * 每周中要禁用的日期。每月中除指定日期外,所有日期都被禁用。
         * 此屬性可更改 DateChooser 控件的外觀。
         * 此數組中的元素可使用介於 0(星期日)到 6(星期六)之間的值。例如,如果設置值 [ 0, 6 ],將禁用星期日和星期六。 
         * 默認值為 []。
         * */
        public function get disabledDays():Array
        {
            return _disabledDays;
        }
 
        /**
         * @private
         */
        public function set disabledDays(value:Array):void
        {
            _disabledDays = value;
        }
 
        /**
         * 禁用一天或多天。 此屬性接受對象 Array 作為參數。
         * 此數組中的所有對象都是 Date 對象,用於指定要禁用的各個日期;也可以是一個包含 rangeStart 和(或)rangeEnd 屬性的對象。
         * 這些屬性的值描述了日期范圍的邊界。如果忽略其中任一屬性,則認為在該方向上無范圍限制。
         * 如果僅指定 rangeStart,則將禁用指定日期之后的所有日期(包括 rangeStart 日期)。
         * 如果僅指定 rangeEnd,則將禁用指定日期之前的所有日期(包括 rangeEnd 日期)。
         * 要禁用單個日期,請使用一個 Date 對象指定 Array 中的某個日期。時間值(如果存在)將以 Date 對象為零值,依次遞增。
         * 以下示例將禁用下列日期:2006 年 1 月 11 日,從 2006 年 1 月 23 至同年 2 月 10 日,以及 2006 年 3 月 1 日及后續所有日期。
         * disabledRanges="{[ new Date(2006,0,11), {rangeStart: new Date(2006,0,23), 
                * rangeEnd: new Date(2006,1,10)}, {rangeStart: new Date(2006,2,1)} ]}"
            * 默認值為 []。
            */
            public function get disabledRanges():Array
            {
            return _disabledRanges;
        }
 
        /**
         * @private
         */
        public function set disabledRanges(value:Array):void
        {
            _disabledRanges = value;
        }
 
        /**
         * 一個數字,該數字代表顯示在 DateChooser 控件第一列中的一周中的日期。
         * 該值必須介於 0 到 6 之間,其中 0 對應星期日,這是 dayNames Array 中的第一個元素。 
         * 設置此屬性將更改日期列的順序。例如,將其設置為 1 可將星期一設置為該控件中的第一列。
         * 默認值為 0 (Sunday)。
         */
        public function get firstDayOfWeek():Object
        {
            return _firstDayOfWeek;
        }
 
        /**
         * @private
         */
        public function set firstDayOfWeek(value:Object):void
        {
            _firstDayOfWeek = value;
        }
 
        /**
         * 此屬性將追加到由 monthNames 屬性指定的值的末尾,用於定義顯示在 DateChooser 控件頂部的月份名稱。
         * 有些語言(如日語)會在月份名稱后使用額外的符號。 默認值為 ""。
         */
        public function get monthSymbol():String
        {
            return _monthSymbol;
        }
 
        /**
         * @private
         */
        public function set monthSymbol(value:String):void
        {
            _monthSymbol = value;
        }
 
        /**
         * 日期范圍,可從中選擇日期。例如,可以選擇 04-12-2006 和 04-12-2007 之間的日期,而超出此范圍的日期將被禁用。 
         * 此屬性接受 Object 作為參數。該 Object 包含 Date 類型的兩個屬性:rangeStart 和 rangeEnd。
         * 如果僅指定了 rangeStart,則在此指定日期之后的所有日期都可用。如果僅指定了 rangeEnd,則在此指定日期之前的所有日期都可用。
         * 要僅在 DateChooser 控件中使用一個日期,可以直接傳遞一個 Date 對象。時間值(如果存在)將以 Date 對象為零值,依次遞增。
         * 以下示例僅啟用 2006 年 1 月 1 日到 2006 年 6 月 30 日的范圍。1 月之前和 6 月之后的月份不會出現在 DateChooser 中。
         * selectableRange="{{rangeStart : new Date(2006,0,1), rangeEnd : new Date(2006,5,30)}}"
            * 默認值為 null
            */
            public function get selectableRange():Object
            {
            return _selectableRange;
        }
 
        /**
         * @private
         */
        public function set selectableRange(value:Object):void
        {
            _selectableRange = value;
        }
 
        /**
         * 在 DateChooser 控件中選擇的日期。如果傳入的 Date 對象包含任何時間值,則它們將被清零。 
         * 在控件中選擇當前所選日期時按住 Ctrl 鍵可取消對該日期的選擇,將 selectedDate 屬性設置為 null,然后分派 change 事件。
         * 默認值為 null。
         */
        public function get selectedDate():Date
        {
            return _selectedDate;
        }
 
        /**
         * @private
         */
        public function set selectedDate(value:Date):void
        {
            _selectedDate = value;
        }
 
        /**
         * 如果為 true,則指定在 DateChooser 控件中加亮顯示今天。設置此屬性可更改 DateChooser 控件的外觀。 
         * 默認值為 true。
         */
        public function get showToday():Boolean
        {
            return _showToday;
        }
 
        /**
         * @private
         */
        public function set showToday(value:Boolean):void
        {
            _showToday = value;
        }
 
        /**
         * 此屬性附加在 DateChooser 控件頂部顯示的年份末尾。有些語言(如日語)會在年份后添加符號。 
         * 默認值為 ""。
         */
        public function get yearSymbol():String
        {
            return _yearSymbol;
        }
 
        /**
         * @private
         */
        public function set yearSymbol(value:String):void
        {
            _yearSymbol = value;
        }
 
        /**
         * 月份日期選擇器日期范圍需要在當前月份推前的月份數,比如現在是2013年7月,
         * 那么默認值48則表示從該日期往前推48個月,也就是說,目前的日期選擇最前可以是2009年7月 
         */
        public function get beforeMonthCount():uint
        {
            return _beforeMonthCount;
        }
 
        /**
         * @private
         */
        public function set beforeMonthCount(value:uint):void
        {
            _beforeMonthCount = value;
        }
 
        /**
         * 月份日期選擇器日期范圍需要在當前月份推后的月份數,比如現在是2013年7月,
         * 值為2則表示從該日期往后推2個月,也就是說,日期選擇最后可以是2013年9月 
         */
        public function get afterMonthCount():uint
        {
            return _afterMonthCount;
        }
 
        /**
         * @private
         */
        public function set afterMonthCount(value:uint):void
        {
            _afterMonthCount = value;
        }
 
        /**
         * 年份日期選擇器日期范圍需要在當前月份推前的月份數,比如現在是2013年
         * 那么默認值4則表示從該日期往前推4年,也就是說,目前的日期選擇最前可以是2009年 
         */
        public function get beforeYearCount():uint
        {
            return _beforeYearCount;
        }
 
        /**
         * @private
         */
        public function set beforeYearCount(value:uint):void
        {
            _beforeYearCount = value;
        }
 
        /**
         * 年份日期選擇器日期范圍需要在當前年份推后的月份數,比如現在是2013年,
         * 值為2則表示從該日期往后推2年,也就是說,日期選擇最后可以是2015年。 
         */
        public function get afterYearCount():uint
        {
            return _afterYearCount;
        }
 
        /**
         * @private
         */
        public function set afterYearCount(value:uint):void
        {
            _afterYearCount = value;
        }
 
        /**
         * 當前默認是選擇哪個日期選擇器,默認是0,日日期選擇器
         */
        public function get selectedIndex():int
        {
            return _selectedIndex;
        }
 
        /**
         * @private
         */
        public function set selectedIndex(value:int):void
        {
            _selectedIndex = value;
        }
 
 
    }
}

 

DateChoosers 繼承了 BorderContainer,在init方法里我們可以看到,它根據自身的屬性日周月年的控制添加了2個DateChooser和2個List,也就是說日和周日期選擇主要是2個DateChooser,而月和年的日期選擇則是2個List。而在DateChooser和List都添加了點擊事件的監聽,在點擊事件之后根據自身特點派發出相應的事件。從而達到日期選擇的目的。
下面來看看使用例子:
<?xml version="1.0" encoding="utf-8"?>
<!-- Simple example to demonstrate the Halo List Control -->
<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"
               xmlns:DateField="DateField.*"
               initialize="application1_initializeHandler(event)">
    <fx:Script>
        <![CDATA[
            import mx.events.FlexEvent;
            
            protected function application1_initializeHandler(event:FlexEvent):void
            {
                // TODO Auto-generated method stub
                dwmDF.dateChoosers.dateLabel = ["日","周","月","年"];
                dwmDF.dateChoosers.afterMonthCount = 4;
                dwmDF.dateChoosers.afterYearCount = 3;
                dwmDF.dateChoosers.disabledRanges = [ {rangeStart: new Date(2013,7,3), rangeEnd: new Date(2013,7,10)}];
            }
            
        ]]>
    </fx:Script>
    
    <fx:Declarations>
        
    </fx:Declarations>
    
    <s:Panel title="DateWeekMouthDateField Example"
             width="75%" height="75%" 
             horizontalCenter="0" verticalCenter="0">
        <s:VGroup left="10" right="10" top="10" bottom="10">
            <DateField:DateWeekMouthDateField id="dwmDF" x="150" y="100">
                
            </DateField:DateWeekMouthDateField>
        </s:VGroup>
    </s:Panel>
    
</s:Application>

 

其中dwmDF.dateChoosers.dateLabel = ["日","周","月","年"];是對日期選擇器標簽的設置,日期選擇器就是由這個標簽來生成的。 總共有["日","周","月","年"]4個日期標簽,如果該值設置為["日","周"]的話,那就只有日周2個日期選擇器。dwmDF.dateChoosers.afterMonthCount = 4;表示月份日期選擇器日期范圍需要在當前月份推后的月份數,比如現在是2013年7月, 值為2則表示從該日期往后推2個月,也就是說,日期選擇最后可以是2013年9月,同理dwmDF.dateChoosers.afterYearCount = 3;是對年份選擇器的設置,年份日期選擇器日期范圍需要在當前年份推后的月份數,比如現在是2013年, 值為2則表示從該日期往后推2年,也就是說,日期選擇最后可以是2015年。dwmDF.dateChoosers.disabledRanges是禁用日期的,這個和DateChooser是一致的。
日周月日期選擇器這樣就功能實現了,在選擇后,我們可以通過dwmDF.dateSlectLabel.text獲取我們選擇的日期內容。
最后附上完整代碼地址:http://files.cnblogs.com/jackyWHJ/DateFieldTest.zip,有需要的童鞋拿去,可以的話給我保留下著作聲明

 

 
 
 


免責聲明!

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



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