使用過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,有需要的童鞋拿去,可以的話給我保留下著作聲明