unity中DatePicker和Calendar

日历效果如下图所示,需要自己搭建UI界面。

DatePicker


/*=========================================
* Author: springDong
* Description: SpringGUI.DatePicker
* DatePicker has lisened onDayClick/onMonthClick/onYearClick three interfaces .
* You can set date by DateTime property.
==========================================*/

using System;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using UnityEngine;

public class DatePicker : MonoBehaviour
{
    private Text _dateText = null;
    private Calendar _calendar = null;
    private DateTime _dateTime = DateTime.Today;

    // get data from this property
    public DateTime DateTime
    {
        get { return _dateTime; }
        set
        {
            _dateTime = value;
            refreshDateText();
        }
    }

    protected  void Awake()
    {
        _dateText = this.transform.Find("DateText").GetComponent<Text>();
        _calendar = this.transform.Find("Calendar").GetComponent<Calendar>();
        _calendar.onDayClick.AddListener(dateTime => { DateTime = dateTime; });
        transform.Find("PickButton").GetComponent<Toggle>().onValueChanged.AddListener((isOn) =>
         {
             if (isOn)
             {
                 _calendar.gameObject.SetActive(true);
             }
             else 
             {
                 _calendar.gameObject.SetActive(false);
             }
             
         });
        refreshDateText();
    }

    private void refreshDateText()
    {
        if (_calendar.DisplayType == E_DisplayType.Standard)
        {
            switch (_calendar.CalendarType)
            {
                case E_CalendarType.Day:
                    _dateText.text = DateTime.ToString("yyyy-MM-dd");
                    break;
                case E_CalendarType.Month:
                    _dateText.text = DateTime.Year + "/" + DateTime.Month;
                    break;
                case E_CalendarType.Year:
                    _dateText.text = DateTime.Year.ToString();
                    break;
            }
        }
        else
        {
            switch (_calendar.CalendarType)
            {
                case E_CalendarType.Day:
                    _dateText.text = DateTime.ToString("yyyy-MM-dd");
                    break;
                case E_CalendarType.Month:
                    _dateText.text = DateTime.Year + "-" + DateTime.Month;
                    break;
                case E_CalendarType.Year:
                    _dateText.text = DateTime.Year.ToString();
                    break;
            }
        }
        _calendar.gameObject.SetActive(false);
    }

    private void Update()
    {

        鼠标左键关闭日历
        //if (Input.GetMouseButtonDown(0)) 
        //{
        //    _calendar.gameObject.SetActive(false);
        //}
    }
}

Calendar


/*=========================================
* Author: springDong
* Description: SpringGUI.Calendar
* This component you only need to listen onDayClick/onMonthClick/onYearClick three interfaces
* Interface return DateTime class data.
==========================================*/

using System;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Collections.Generic;
using UnityEngine.Events;
using Object = UnityEngine.Object;

public class Calendar : MonoBehaviour
    {
        #region click events
        public class DayClickEvent : UnityEvent<DateTime>{}
        public class MonthClickEvent : UnityEvent<DateTime> { }
        public class YearClickEvent : UnityEvent<DateTime> { }

        private DayClickEvent m_onDayClickEvent = new DayClickEvent();
        public DayClickEvent onDayClick
        {
            get { return m_onDayClickEvent; }
            set { m_onDayClickEvent = value; }
        }
        private MonthClickEvent m_onMonthClickEvent = new MonthClickEvent();
        public MonthClickEvent onMonthClick
        {
            get { return m_onMonthClickEvent; }
            set { m_onMonthClickEvent = value; }
        }
        private YearClickEvent m_onYearClickEvent = new YearClickEvent();
        public YearClickEvent onYearClick
        {
            get { return m_onYearClickEvent; }
            set { m_onYearClickEvent = value; }
        }

        #endregion

        #region private && public members
        private DateTime m_selectDT = DateTime.Today;
        private readonly CalendarData m_calendarData = new CalendarData();
        private Transform m_Transform = null;
        [HideInInspector]
        public E_CalendarType CalendarType = E_CalendarType.Day;
        public E_DisplayType DisplayType = E_DisplayType.Chinese;
        private Text _timeButtonText = null;
        private GameObject _weeksGameObject = null;
        private GameObject _daysGameObejct = null;
        private GameObject _monthGameObject = null;
        private readonly List<DMY> _daysPool = new List<DMY>();
        private readonly List<DMY> _monthYearPool = new List<DMY>();
        #endregion

        protected  void Awake()
        {
            m_Transform = transform;
            _timeButtonText = m_Transform.Find("Title/TimeButton/Text").GetComponent<Text>();
            _weeksGameObject = m_Transform.Find("Container/Weeks").gameObject;
            _daysGameObejct = m_Transform.Find("Container/Days").gameObject;
            _monthGameObject = m_Transform.Find("Container/Months").gameObject;
            var weekPrefab = _weeksGameObject.transform.Find("WeekTemplate").gameObject;
            var dayPrefab = _daysGameObejct.transform.Find("DayTemplate").gameObject;
            var monthPrefab = _monthGameObject.transform.Find("MonthTemplate").gameObject;
            WeekGenerator(weekPrefab, _weeksGameObject.transform);
            DayGenerator(dayPrefab, _daysGameObejct.transform);
            MonthGenerator(monthPrefab, _monthGameObject.transform);
            m_Transform.Find("Title/NextButton").GetComponent<Button>().onClick.AddListener(OnNextButtonClick);
            m_Transform.Find("Title/LastButton").GetComponent<Button>().onClick.AddListener(OnLastButtonClick);
            m_Transform.Find("Title/TimeButton").GetComponent<Button>().onClick.AddListener(OnTimeButtonClick);
            Refresh();
        }

        #region operation functions
        private void OnTimeButtonClick()
        {
            if ( CalendarType == E_CalendarType.Month )
                CalendarType = E_CalendarType.Year;
            if (CalendarType == E_CalendarType.Day)
            {
                CalendarType = E_CalendarType.Month;
                calendarTypeChange(false);
            }
            Refresh();
        }
        private void OnNextButtonClick()
        {
            if ( CalendarType == E_CalendarType.Day )
                m_selectDT = m_selectDT.AddMonths(1);
            else if ( CalendarType == E_CalendarType.Month )
                m_selectDT = m_selectDT.AddYears(1);
            else 
                m_selectDT = m_selectDT.AddYears(12);
            Refresh();
        }
        private void OnLastButtonClick()
        {
            if(CalendarType == E_CalendarType.Day)
                m_selectDT = m_selectDT.AddMonths(-1);
            else if(CalendarType == E_CalendarType.Month)
                m_selectDT = m_selectDT.AddYears(-1);
            else 
                m_selectDT = m_selectDT.AddYears(-12);
            Refresh();
        }
        #endregion

        #region days && weeks && months generator
        private void WeekGenerator( GameObject weekPrefab ,Transform parent )
        {
            for (int i = 0; i < 7; i++)
            {
                GameObject week = prefabGenerator(weekPrefab , parent);
                week.GetComponent<Text>().text = getWeekName(i.ToString());
            }
            Destroy(weekPrefab);
        }
        private void DayGenerator( GameObject dayPrefab , Transform parent )
        {
            for (int i = 0; i < 42; i++)
            {
                GameObject day = prefabGenerator(dayPrefab,parent);
                DMY dmy = day.AddComponent<DMY>();
                day.GetComponent<Button>().onClick.AddListener(() =>
                {
                    m_selectDT = dmy.DateTime;
                    onDayClick.Invoke(dmy.DateTime);
                    Refresh();
                });
                _daysPool.Add(dmy);
            }
            Destroy(dayPrefab);
        }
        private void MonthGenerator( GameObject monthPrefab , Transform parent )
        {
            for ( int i = 0 ; i < 12 ; i++ )
            {
                GameObject month = prefabGenerator(monthPrefab , parent);
                DMY dmy = month.AddComponent<DMY>();
                month.GetComponent<Button>().onClick.AddListener(() =>
                {
                    m_selectDT = dmy.DateTime;
                    if ( CalendarType == E_CalendarType.Month )
                    {
                        CalendarType = E_CalendarType.Day;
                        calendarTypeChange(true);
                        onMonthClick.Invoke(dmy.DateTime);
                    }
                    if (CalendarType == E_CalendarType.Year)
                    {
                        CalendarType = E_CalendarType.Month;
                        onYearClick.Invoke(dmy.DateTime);
                    }
                    Refresh();
                });
                _monthYearPool.Add(dmy);
            }
            Destroy(monthPrefab);
        }
        private GameObject prefabGenerator( GameObject prefab,Transform parent )
        {
            GameObject go = Object.Instantiate(prefab);
            go.transform.SetParent(parent);
            go.transform.localScale = Vector3.one;
            return go;
        }
        private string getWeekName( string weekName )
        {
            switch (DisplayType)
            {
                case E_DisplayType.Standard:
                    switch ( weekName )
                    {
                        case "0":
                            return "Sunday";
                        case "1":
                            return "Monday";
                        case "2":
                            return "Tuesday";
                        case "3":
                            return "Wednesday";
                        case "4":
                            return "Thursday";
                        case "5":
                            return "Friday";
                        case "6":
                            return "Saturday";
                        default:
                            return "";
                    }
                case E_DisplayType.Chinese:
                    switch ( weekName )
                    {
                        case "0":
                            return "日";
                        case "1":
                            return "一";
                        case "2":
                            return "二";
                        case "3":
                            return "三";
                        case "4":
                            return "四";
                        case "5":
                            return "五";
                        case "6":
                            return "六";
                        default:
                            return "";
                    }
                default:
                    return "";
            }
            
        }
        private void calendarTypeChange( bool isDays )
        {
            _weeksGameObject.SetActive(isDays);
            _daysGameObejct.SetActive(isDays);
            _monthGameObject.SetActive(!isDays);
        }
        #endregion

        #region refresh calendar all component
        private void Refresh( )
        {
            RefreshCalendar();
            RefreshTimeButtonContent();
        }
        private void RefreshTimeButtonContent( )
        {
            switch ( CalendarType )
            {
                case E_CalendarType.Day:
                    if ( DisplayType == E_DisplayType.Standard ) _timeButtonText.text = m_selectDT.ToShortDateString();
                    else _timeButtonText.text = m_selectDT.Year + "年" + m_selectDT.Month + "月" + m_selectDT.Day + "日";
                    break;
                case E_CalendarType.Month:
                    if ( DisplayType == E_DisplayType.Standard ) _timeButtonText.text = m_selectDT.Year + "/" + m_selectDT.Month;
                    else _timeButtonText.text = m_selectDT.Year + "年" + m_selectDT.Month + "月";
                    break;
                case E_CalendarType.Year:
                    if ( DisplayType == E_DisplayType.Standard ) _timeButtonText.text = m_selectDT.Year.ToString();
                    else _timeButtonText.text = m_selectDT.Year + "年";
                    break;
            }
        }
        private void RefreshCalendar( )
        {
            if(CalendarType == E_CalendarType.Day) RefreshDays(m_calendarData.Days(m_selectDT));
            else if(CalendarType == E_CalendarType.Month) RefreshMonths(m_calendarData.Months(m_selectDT));
            else RefreshYears(m_calendarData.Years(m_selectDT));
        }
        private void RefreshDays( List<DateTime> dateTimes )
        {
            for (int i = 0; i < _daysPool.Count; i++)
            {
                var fontColor = Color.black;
                if (dateTimes[i].Month != m_selectDT.Month)
                    fontColor = Color.gray;
                _daysPool[i].SetDay(dateTimes[i] , DisplayType , fontColor);
            }
        }
        private void RefreshMonths( List<DateTime> dateTimes )
        {
            for ( int i = 0 ; i < _monthYearPool.Count ; i++ )
                _monthYearPool[i].SetMonth(dateTimes[i] , DisplayType);
        }
        private void RefreshYears( List<DateTime> dateTimes )
        {
            for ( int i = 0 ; i < _monthYearPool.Count ; i++ )
                _monthYearPool[i].SetYear(dateTimes[i] , DisplayType);
        }
        #endregion
    }

    public enum E_CalendarType
    {
        Day,
        Month,
        Year
    }
    public enum E_DisplayType
    {
        Standard,
        Chinese
    }
    public class CalendarData
    {
        public List<DateTime> Days( DateTime month )
        {
            List<DateTime> days = new List<DateTime>();
            DateTime firstDay = new DateTime(month.Year , month.Month , 1);
            DayOfWeek week = firstDay.DayOfWeek;
            int lastMonthDays = (int)week;
            if ( lastMonthDays.Equals(0) )
                lastMonthDays = 7;
            for ( int i = lastMonthDays ; i > 0 ; i-- )
                days.Add(firstDay.AddDays(-i));
            for ( int i = 0 ; i < 42 - lastMonthDays ; i++ )
                days.Add(firstDay.AddDays(i));
            return days;
        }
        public List<DateTime> Months( DateTime year )
        {
            List<DateTime> months = new List<DateTime>();
            DateTime firstMonth = new DateTime(year.Year , 1 , 1);
            months.Add(firstMonth);
            for ( int i = 1 ; i < 12 ; i++ )
                months.Add(firstMonth.AddMonths(i));
            return months;
        }
        public List<DateTime> Years( DateTime year )
        {
            List<DateTime> years = new List<DateTime>();
            for ( int i = 5 ; i > 0 ; i-- )
                years.Add(year.AddYears(-i));
            for ( int i = 0 ; i < 7 ; i++ )
                years.Add(year.AddYears(i));
            return years;
        }
    }
    public class DMY : MonoBehaviour
    {
        public DateTime DateTime { get; set; }
        private Text _text = null;
        protected  void Awake( )
        {
            _text = transform.Find("Text").GetComponent<Text>();
        }
        public void SetDay( DateTime dateTime , E_DisplayType displayType , Color fontColor )
        {
            DateTime = dateTime;
            _text.text = dateTime.Day.ToString();
            _text.color = fontColor;
        }
        public void SetMonth( DateTime dateTime , E_DisplayType displayType )
        {
            DateTime = dateTime;
            _text.text = getMonthString(dateTime.Month.ToString() , displayType);
        }
        public void SetYear( DateTime dateTime , E_DisplayType displayType )
        {
            DateTime = dateTime;
            _text.text = dateTime.Year.ToString();
        }
        private string getMonthString( string month , E_DisplayType displayType )
        {
            switch ( displayType )
            {
                case E_DisplayType.Standard:
                    switch ( month )
                    {
                        case "1":
                            return "Jan.";
                        case "2":
                            return "Feb.";
                        case "3":
                            return "Mar.";
                        case "4":
                            return "Apr.";
                        case "5":
                            return "May.";
                        case "6":
                            return "Jun.";
                        case "7":
                            return "Jul.";
                        case "8":
                            return "Aug.";
                        case "9":
                            return "Sept.";
                        case "10":
                            return "Oct.";
                        case "11":
                            return "Nov.";
                        case "12":
                            return "Dec.";
                        default:
                            return "";
                    }
                case E_DisplayType.Chinese:
                    switch ( month )
                    {
                        case "1":
                            return "一月";
                        case "2":
                            return "二月";
                        case "3":
                            return "三月";
                        case "4":
                            return "四月";
                        case "5":
                            return "五月";
                        case "6":
                            return "六月";
                        case "7":
                            return "七月";
                        case "8":
                            return "八月";
                        case "9":
                            return "九月";
                        case "10":
                            return "十月";
                        case "11":
                            return "十一月";
                        case "12":
                            return "十二月";
                        default:
                            return "";
                    }
                default:
                    return "";
            }
        }
    }

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值