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获取我们选择的日期内容。
最后附上完整代码地址:https://files.cnblogs.com/jackyWHJ/DateFieldTest.zip,有需要的童鞋拿去,可以的话给我保留下著作声明