solarHodilays = new HashMap<>();
26 |
27 | public static SpecialDayUtil getInstance() {
28 | if (mSpecailDay == null) {
29 | mSpecailDay = new SpecialDayUtil();
30 | }
31 | return mSpecailDay;
32 | }
33 |
34 | public SpecialDayUtil() {
35 | // 添加法定节假日
36 | addGovHoliday();
37 | // 添加节假日前后调休工作日
38 | addGovHolidayWork();
39 | // 添加农历节日
40 | addLunarHolidays();
41 | // 添加公历节日
42 | addSolarHolidays();
43 |
44 | }
45 |
46 | /**
47 | * 法定节假日
48 | * 需手动维护
49 | */
50 | private void addGovHoliday() {
51 | // 元旦
52 | govHoldays.add("2017-12-30");
53 | govHoldays.add("2017-12-31");
54 | govHoldays.add("2018-01-01");
55 | // 春节
56 | govHoldays.add("2018-02-15");
57 | govHoldays.add("2018-02-16");
58 | govHoldays.add("2018-02-17");
59 | govHoldays.add("2018-02-18");
60 | govHoldays.add("2018-02-19");
61 | govHoldays.add("2018-02-20");
62 | govHoldays.add("2018-02-21");
63 | // 清明
64 | govHoldays.add("2018-04-05");
65 | govHoldays.add("2018-04-06");
66 | govHoldays.add("2018-04-07");
67 | // 五一
68 | govHoldays.add("2018-04-29");
69 | govHoldays.add("2018-04-30");
70 | govHoldays.add("2018-05-01");
71 | // 端午
72 | govHoldays.add("2018-06-16");
73 | govHoldays.add("2018-06-17");
74 | govHoldays.add("2018-06-18");
75 | // 端午
76 | govHoldays.add("2018-09-22");
77 | govHoldays.add("2018-09-23");
78 | govHoldays.add("2018-09-24");
79 | // 国庆
80 | govHoldays.add("2018-10-01");
81 | govHoldays.add("2018-10-02");
82 | govHoldays.add("2018-10-03");
83 | govHoldays.add("2018-10-04");
84 | govHoldays.add("2018-10-05");
85 | govHoldays.add("2018-10-06");
86 | govHoldays.add("2018-10-07");
87 | }
88 |
89 | /**
90 | * 法定节假日调休
91 | * 周末为工作日的情况
92 | * 需手动维护
93 | */
94 | private void addGovHolidayWork() {
95 | //春节
96 | workInHoliday.add("2018-02-11");
97 | workInHoliday.add("2018-02-24");
98 | //清明
99 | workInHoliday.add("2018-04-08");
100 | //五一
101 | workInHoliday.add("2018-04-28");
102 | //十一
103 | workInHoliday.add("2018-09-29");
104 | workInHoliday.add("2018-09-30");
105 | }
106 |
107 | /**
108 | * 添加公历节日
109 | */
110 | private void addLunarHolidays() {
111 | lunarHodilays.put("12-08", "腊八");
112 | lunarHodilays.put("12-30", "除夕");
113 | lunarHodilays.put("01-01", "春节");
114 | lunarHodilays.put("01-15", "元宵节");
115 | lunarHodilays.put("05-05", "端午节");
116 | lunarHodilays.put("07-07", "七夕");
117 | lunarHodilays.put("07-15", "中元节");
118 | lunarHodilays.put("08-15", "中秋节");
119 | lunarHodilays.put("09-09", "重阳节");
120 | }
121 |
122 | /**
123 | * 添加公历节日
124 | */
125 | private void addSolarHolidays() {
126 | solarHodilays.put("01-01", "元旦");
127 | solarHodilays.put("02-14", "情人节");
128 | solarHodilays.put("03-08", "妇女节");
129 | solarHodilays.put("03-12", "植树节");
130 | solarHodilays.put("04-01", "愚人节");
131 | solarHodilays.put("04-05", "清明节");
132 | solarHodilays.put("05-01", "劳动节");
133 | solarHodilays.put("05-04", "青年节");
134 | solarHodilays.put("06-01", "儿童节");
135 | solarHodilays.put("07-01", "建党节");
136 | solarHodilays.put("08-01", "建军节");
137 | solarHodilays.put("09-10", "教师节");
138 | solarHodilays.put("10-01", "国庆节");
139 | solarHodilays.put("11-11", "双11");
140 | solarHodilays.put("12-25", "圣诞节");
141 | }
142 |
143 | /**
144 | * 是否为法定节假日
145 | *
146 | * @param calendar
147 | */
148 | public boolean isGovHoliday(Calendar calendar) {
149 | String dayStr = sdf.format(calendar.getTime());
150 | return govHoldays.contains(dayStr);
151 | }
152 |
153 | /**
154 | * 是否法定节假日前后调休工作日
155 | *
156 | * @param calendar
157 | * @return
158 | */
159 | public boolean isGovHolidayWork(Calendar calendar) {
160 | String dayStr = sdf.format(calendar.getTime());
161 | return workInHoliday.contains(dayStr);
162 | }
163 |
164 | /**
165 | * 获取节假日名称
166 | *
167 | * @param calendar
168 | * @return
169 | */
170 | public String getHolidayName(Calendar calendar) {
171 | String solarDate = sdf2.format(calendar.getTime());
172 | String holidayName = solarHodilays.get(solarDate);
173 | if (TextUtils.isEmpty(holidayName)) {
174 | String lunarDate = new LunarDayUtil(calendar).toLunarFormatDay();
175 | holidayName = lunarHodilays.get(lunarDate);
176 | }
177 | return holidayName;
178 | }
179 | }
180 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/app/src/main/java/com/wugj/calendar/LunarDayUtil.java:
--------------------------------------------------------------------------------
1 | package com.wugj.calendar;
2 |
3 | import java.text.ParseException;
4 | import java.text.SimpleDateFormat;
5 | import java.util.Calendar;
6 | import java.util.Date;
7 |
8 | /**
9 | * 农历计算工具类
10 | *
11 | * @author wuguojin
12 | * @date 2018/6/11
13 | *
14 | * 使用步骤是在Activity里
15 | * Calendar calendar=Calendar.getInstance();
16 | * Lunar lunar = new Lunar(calendar);
17 | * lunar.animalsYear();//生肖
18 | * lunar.cyclical();//农历的干支甲子
19 | * lunar.toString();//农历的月日
20 | */
21 | public class LunarDayUtil {
22 |
23 | private int year;
24 | private int month;
25 | private int day;
26 | private boolean leap;
27 | final static String chineseNumber[] = {"一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二"};
28 | static SimpleDateFormat chineseDateFormat = new SimpleDateFormat("yyyy年MM月dd日");
29 | final static long[] lunarInfo = new long[]
30 | {0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2,
31 | 0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977,
32 | 0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970,
33 | 0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950,
34 | 0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557,
35 | 0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5d0, 0x14573, 0x052d0, 0x0a9a8, 0x0e950, 0x06aa0,
36 | 0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0,
37 | 0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b5a0, 0x195a6,
38 | 0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570,
39 | 0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0,
40 | 0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5,
41 | 0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930,
42 | 0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530,
43 | 0x05aa0, 0x076a3, 0x096d0, 0x04bd7, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45,
44 | 0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0};
45 |
46 |
47 | //====== 传回农历 y年的总天数
48 | final private static int yearDays(int y) {
49 | int i, sum = 348;
50 | for (i = 0x8000; i > 0x8; i >>= 1) {
51 | if ((lunarInfo[y - 1900] & i) != 0) sum += 1;
52 | }
53 | return (sum + leapDays(y));
54 | }
55 |
56 |
57 | //====== 传回农历 y年闰月的天数
58 | final private static int leapDays(int y) {
59 | if (leapMonth(y) != 0) {
60 | if ((lunarInfo[y - 1900] & 0x10000) != 0)
61 | return 30;
62 | else
63 | return 29;
64 | } else
65 | return 0;
66 | }
67 |
68 |
69 | //====== 传回农历 y年闰哪个月 1-12 , 没闰传回 0
70 | final private static int leapMonth(int y) {
71 | return (int) (lunarInfo[y - 1900] & 0xf);
72 | }
73 |
74 |
75 | //====== 传回农历 y年m月的总天数
76 | final private static int monthDays(int y, int m) {
77 | if ((lunarInfo[y - 1900] & (0x10000 >> m)) == 0)
78 | return 29;
79 | else
80 | return 30;
81 | }
82 |
83 |
84 | //====== 传回农历 y年的生肖
85 | final public String animalsYear() {
86 | final String[] Animals = new String[]{"鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪"};
87 | return Animals[(year - 4) % 12];
88 | }
89 |
90 |
91 | //====== 传入 月日的offset 传回干支, 0=甲子
92 | final private static String cyclicalm(int num) {
93 | final String[] Gan = new String[]{"甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"};
94 | final String[] Zhi = new String[]{"子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"};
95 | return (Gan[num % 10] + Zhi[num % 12]);
96 | }
97 |
98 |
99 | //====== 传入 offset 传回干支, 0=甲子
100 | final public String cyclical() {
101 | int num = year - 1900 + 36;
102 | return (cyclicalm(num));
103 | }
104 |
105 | public String getLunarMonthString() {
106 | // TODO Auto-generated method stub
107 | return null;
108 | }
109 |
110 |
111 | public LunarDayUtil(Calendar cal) {
112 | @SuppressWarnings("unused") int yearCyl, monCyl, dayCyl;
113 | int leapMonth = 0;
114 | Date baseDate = null;
115 | try {
116 | baseDate = chineseDateFormat.parse("1900年1月31日");
117 | } catch (ParseException e) {
118 | e.printStackTrace(); //To change body of catch statement use Options | File Templates.
119 | }
120 |
121 |
122 | //求出和1900年1月31日相差的天数
123 | int offset = (int) ((cal.getTime().getTime() - baseDate.getTime()) / 86400000L);
124 | dayCyl = offset + 40;
125 | monCyl = 14;
126 |
127 |
128 | //用offset减去每农历年的天数
129 | // 计算当天是农历第几天
130 | //i最终结果是农历的年份
131 | //offset是当年的第几天
132 | int iYear, daysOfYear = 0;
133 | for (iYear = 1900; iYear < 2050 && offset > 0; iYear++) {
134 | daysOfYear = yearDays(iYear);
135 | offset -= daysOfYear;
136 | monCyl += 12;
137 | }
138 | if (offset < 0) {
139 | offset += daysOfYear;
140 | iYear--;
141 | monCyl -= 12;
142 | }
143 | //农历年份
144 | year = iYear;
145 |
146 | yearCyl = iYear - 1864;
147 | leapMonth = leapMonth(iYear); //闰哪个月,1-12
148 | leap = false;
149 |
150 |
151 | //用当年的天数offset,逐个减去每月(农历)的天数,求出当天是本月的第几天
152 | int iMonth, daysOfMonth = 0;
153 | for (iMonth = 1; iMonth < 13 && offset > 0; iMonth++) {
154 | //闰月
155 | if (leapMonth > 0 && iMonth == (leapMonth + 1) && !leap) {
156 | --iMonth;
157 | leap = true;
158 | daysOfMonth = leapDays(year);
159 | } else {
160 | daysOfMonth = monthDays(year, iMonth);
161 | }
162 |
163 |
164 | offset -= daysOfMonth;
165 | //解除闰月
166 | if (leap && iMonth == (leapMonth + 1)) leap = false;
167 | if (!leap) monCyl++;
168 | }
169 | //offset为0时,并且刚才计算的月份是闰月,要校正
170 | if (offset == 0 && leapMonth > 0 && iMonth == leapMonth + 1) {
171 | if (leap) {
172 | leap = false;
173 | } else {
174 | leap = true;
175 | --iMonth;
176 | --monCyl;
177 | }
178 | }
179 | //offset小于0时,也要校正
180 | if (offset < 0) {
181 | offset += daysOfMonth;
182 | --iMonth;
183 | --monCyl;
184 | }
185 | month = iMonth;
186 | day = offset + 1;
187 | }
188 |
189 |
190 | public static String getChinaDayString(int day) {
191 | String chineseTen[] = {"初", "十", "廿", "三"};
192 | int n = day % 10 == 0 ? 9 : day % 10 - 1;
193 | if (day > 30)
194 | return "";
195 | if (day == 10)
196 | return "初十";
197 | else
198 | return chineseTen[day / 10] + chineseNumber[n];
199 | }
200 |
201 |
202 | @Override
203 | public String toString() {
204 | return (leap ? "闰" : "") + chineseNumber[month - 1] + "月" + getChinaDayString(day);
205 | }
206 |
207 | /**
208 | * 返回简单农历日
209 | *
210 | * @return
211 | */
212 | public String toStringSimpleDay() {
213 | if (getChinaDayString(day).equals("初一")) {
214 | return chineseNumber[month - 1] + "月";
215 | }
216 | return getChinaDayString(day);
217 | }
218 |
219 | /**
220 | * 返回MM-dd的农历格式
221 | *
222 | * @return
223 | */
224 | public String toLunarFormatDay() {
225 | return ((month < 10) ? ("0" + month) : month) + "-" +
226 | ((day < 10) ? ("0" + day) : day);
227 | }
228 | }
229 |
--------------------------------------------------------------------------------
/app/src/main/java/com/wugj/calendar/CalendarActivity.java:
--------------------------------------------------------------------------------
1 | package com.wugj.calendar;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.graphics.Color;
7 | import android.os.AsyncTask;
8 | import android.os.Bundle;
9 | import android.os.Handler;
10 | import android.support.annotation.Nullable;
11 | import android.support.design.widget.TabLayout;
12 | import android.support.v7.app.AppCompatActivity;
13 | import android.support.v7.widget.GridLayoutManager;
14 | import android.support.v7.widget.LinearLayoutManager;
15 | import android.support.v7.widget.RecyclerView;
16 | import android.support.v7.widget.Toolbar;
17 | import android.text.TextUtils;
18 | import android.util.TypedValue;
19 | import android.view.Gravity;
20 | import android.view.LayoutInflater;
21 | import android.view.MenuItem;
22 | import android.view.View;
23 | import android.view.ViewGroup;
24 | import android.widget.LinearLayout;
25 | import android.widget.RelativeLayout;
26 | import android.widget.TextView;
27 |
28 | import com.huicent.library.loadwidget.AVLoadingIndicatorView;
29 | import com.huicent.library.utils.ThreadPoolProxy;
30 | import com.huicent.library.utils.ToastUtils;
31 |
32 | import java.util.ArrayList;
33 | import java.util.Calendar;
34 | import java.util.Date;
35 | import java.util.HashMap;
36 | import java.util.List;
37 |
38 | /**
39 | * 价格日期页面
40 | *
41 | * @author wuguojin
42 | * @date 2018/6/8
43 | */
44 | public class CalendarActivity extends AppCompatActivity implements CalendarListener {
45 |
46 | /**
47 | * Fragment启动日历并获取结果
48 | *
49 | * @param fragment
50 | * @param pickerMode
51 | * @param reqCode
52 | */
53 | public static void startForResult(android.support.v4.app.Fragment fragment,
54 | int pickerMode, DateBean depDate, int reqCode) {
55 | Intent intent = new Intent(fragment.getContext(), CalendarActivity.class);
56 | intent.putExtra("pickerMode", pickerMode);
57 | if (depDate != null) {
58 | intent.putExtra("depDate", depDate);
59 | }
60 | fragment.startActivityForResult(intent, reqCode);
61 | }
62 |
63 | /**
64 | * Activity启动日历并获取结果
65 | *
66 | * @param activity
67 | * @param pickerMode
68 | * @param reqCode
69 | */
70 | public static void startForResult(Activity activity,
71 | int pickerMode, DateBean depDate, int reqCode) {
72 | Intent intent = new Intent(activity, CalendarActivity.class);
73 | intent.putExtra("pickerMode", pickerMode);
74 | if (depDate != null) {
75 | intent.putExtra("depDate", depDate);
76 | }
77 | activity.startActivityForResult(intent, reqCode);
78 | }
79 |
80 | public enum MODE {
81 | SINGLE(1), // 单程
82 | ROUND(2); // 往返
83 |
84 | private int iNum = 0;
85 |
86 | private MODE(int iNum) {
87 | this.iNum = iNum;
88 | }
89 |
90 | public int toNumber() {
91 | return this.iNum;
92 | }
93 |
94 | }
95 |
96 | private static Context mContext;
97 | private int pickerMode; //取日期类型,1-单程 2-往返
98 |
99 | protected TextView barTitle;
100 | protected Toolbar toolbar;
101 | private TabLayout roundTripTop;
102 |
103 | RelativeLayout progressLayout;
104 | AVLoadingIndicatorView loadingView;
105 | LinearLayout containerLayout;
106 |
107 | LinearLayout weekLayout;
108 | RecyclerView recyclerView;
109 | RecyclerAdapter groupAdatper;
110 | private List calendars = new ArrayList<>();
111 | private int[] startToEndMonth = {0, 7};
112 | private static String[] weeks = {"日", "一", "二", "三", "四", "五", "六"};
113 | private HashMap priceMap = new HashMap<>();
114 | private Handler mHandler = new Handler();
115 |
116 | @Override
117 | protected void onCreate(@Nullable Bundle savedInstanceState) {
118 | super.onCreate(savedInstanceState);
119 | mContext = this;
120 | setContentView(R.layout.calendar_activity_layout);
121 | initBundle();
122 | initActionBar();
123 | initProgressView();
124 | new CalendarAsync().execute();
125 | }
126 |
127 | class CalendarAsync extends AsyncTask {
128 |
129 | @Override
130 | protected void onPreExecute() {
131 | containerLayout.setVisibility(View.GONE);
132 | progressLayout.setVisibility(View.VISIBLE);
133 | loadingView.show();
134 | }
135 |
136 | @Override
137 | protected Boolean doInBackground(Void... params) {
138 | try {
139 | initData();
140 | } catch (Exception e) {
141 | return false;
142 | }
143 | return true;
144 | }
145 |
146 | @Override
147 | protected void onPostExecute(Boolean result) {
148 | loadingView.hide();
149 | progressLayout.setVisibility(View.GONE);
150 | containerLayout.setVisibility(View.VISIBLE);
151 | initView();
152 | initPrice();
153 | }
154 | }
155 |
156 | private void initBundle() {
157 | pickerMode = getIntent().getIntExtra("pickerMode", 1);
158 | roundModeDepDate = (DateBean) getIntent().getSerializableExtra("depDate");
159 | }
160 |
161 | public void initActionBar() {
162 | toolbar = (Toolbar) findViewById(R.id.base_toolbar);
163 | barTitle = (TextView) findViewById(R.id.bar_title);
164 | setSupportActionBar(toolbar);
165 | getSupportActionBar().setTitle("");
166 | setBarTitle("日期选择");
167 | setBarBack(true);
168 | }
169 |
170 | private void initProgressView() {
171 | progressLayout = (RelativeLayout) findViewById(R.id.progress_ll);
172 | loadingView = (AVLoadingIndicatorView) findViewById(R.id.av_loading_view);
173 | containerLayout = (LinearLayout) findViewById(R.id.container_ll);
174 | }
175 |
176 | private void initData() {
177 | Calendar todayCalendar = Calendar.getInstance();
178 | todayCalendar.setTime(new Date());
179 |
180 | CalendarBean calendarBean = null;
181 | int groupIndex = 0;
182 | for (int i = startToEndMonth[0]; i <= startToEndMonth[1]; i++) {
183 | calendarBean = new CalendarBean();
184 | Calendar calendarClone = (Calendar) todayCalendar.clone();
185 | calendarClone.add(Calendar.MONTH, i);
186 | calendarClone.set(Calendar.DATE, 1);
187 | calendarBean.setYear(calendarClone.get(Calendar.YEAR));
188 | calendarBean.setMonth(calendarClone.get(Calendar.MONTH) + 1);
189 | calendarBean.setShownTitle(calendarBean.getYear() + "-" + calendarBean.getMonth());
190 |
191 | // 1-星期天 7-星期六
192 | int dayOfWeek = calendarClone.get(Calendar.DAY_OF_WEEK);
193 | //上月的最后几天展示在本月
194 | int emptyCount = dayOfWeek - 1;
195 | calendarClone.roll(Calendar.DATE, -1);
196 | // 当月的最大天数
197 | int maxDays = calendarClone.get(Calendar.DATE);
198 |
199 | List daysList = new ArrayList<>();
200 | int maxRows = 5;
201 | if (emptyCount + maxDays > 35) {
202 | //当月有效日期+1号前空白日期个数>35,则当月需要6行
203 | maxRows = 6;
204 | }
205 | for (int j = 0; j < (maxRows * 7); j++) {
206 | DateBean dayItem = new DateBean();
207 | // 用于控制定位
208 | dayItem.setGroupIndex(groupIndex);
209 | dayItem.setChildIndex(j);
210 |
211 | Calendar calendarDayClone = (Calendar) calendarClone.clone();
212 | if (j < emptyCount) {
213 | dayItem.setCanSelect(false);
214 | //上月最后几天
215 | calendarDayClone.add(Calendar.DATE, (j - emptyCount));
216 | dayItem.setShownDay("");
217 | dayItem.setNongliDay("");
218 | daysList.add(dayItem);
219 |
220 | continue;
221 | }
222 | if (j >= emptyCount + maxDays) {
223 | dayItem.setCanSelect(false);
224 | //下月头几天
225 | calendarDayClone.add(Calendar.MONTH, 1);
226 | calendarDayClone.set(Calendar.DATE, j - (emptyCount + maxDays) + 1);
227 | dayItem.setShownDay("");
228 | dayItem.setNongliDay("");
229 | daysList.add(dayItem);
230 |
231 | continue;
232 | }
233 | calendarDayClone.set(Calendar.DATE, j - emptyCount + 1);
234 | //显示的日期
235 | dayItem.setShownDay(String.valueOf(calendarDayClone.get(Calendar.DATE)));
236 | //显示的农历
237 | dayItem.setNongliDay(new LunarDayUtil(calendarDayClone).toStringSimpleDay());
238 | //显示的特殊日子
239 | dayItem.setSpecialDayTag(SpecialDayUtil.getInstance().getHolidayName(calendarDayClone));
240 |
241 | dayItem.setYear(calendarDayClone.get(Calendar.YEAR));
242 | dayItem.setMonth(calendarDayClone.get(Calendar.MONTH) + 1);
243 | dayItem.setDay(calendarDayClone.get(Calendar.DATE));
244 | dayItem.setDayOfWeek(calendarDayClone.get(Calendar.DAY_OF_WEEK));
245 | dayItem.setGovHoliday(SpecialDayUtil.getInstance().isGovHoliday(calendarDayClone));
246 | dayItem.setGovHolidayWork(SpecialDayUtil.getInstance().isGovHolidayWork(calendarDayClone));
247 |
248 | if (calendarDayClone.before(todayCalendar)) {
249 | //今天之前
250 | dayItem.setCanSelect(false);
251 | } else if (calendarDayClone.equals(todayCalendar)) {
252 | dayItem.setShownDay("今天");
253 | dayItem.setCanSelect(true);
254 | } else {
255 | //今天之后
256 | dayItem.setCanSelect(true);
257 | }
258 | dayItem.setSaverCalendar(calendarDayClone);
259 |
260 | daysList.add(dayItem);
261 | }
262 | calendarBean.setDateBeans(daysList);
263 | calendars.add(calendarBean);
264 | groupIndex++;
265 | }
266 | }
267 |
268 | private void initView() {
269 | roundTripTop = (TabLayout) findViewById(R.id.round_trip_top);
270 | weekLayout = (LinearLayout) findViewById(R.id.week_layout);
271 | recyclerView = (RecyclerView) findViewById(R.id.recycler_calendar);
272 | recyclerView.setLayoutManager(new LinearLayoutManager(this));
273 | groupAdatper = new RecyclerAdapter(calendars, this);
274 | recyclerView.setAdapter(groupAdatper);
275 |
276 | if (pickerMode == MODE.ROUND.toNumber()) {
277 | roundTripTop.setVisibility(View.VISIBLE);
278 | if (roundModeDepDate != null) {
279 | roundTripTop.getTabAt(0).setText("去程\n" + roundModeDepDate.getFomartTag());
280 | roundTripTop.getTabAt(1).select();
281 | setCalendarEnableRange(roundModeDepDate);
282 | }
283 | roundTripTop.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
284 | @Override
285 | public void onTabSelected(TabLayout.Tab tab) {
286 | if (tab.getPosition() == 0) {
287 | // 清除去程日期,并且可选范围改变至当天以后
288 | if (roundModeDepDate == null) {
289 | return;
290 | }
291 | roundModeDepDate = null;
292 | tab.setText("去程");
293 | DateBean todayBean = calendars.get(0).getDateBeans().get(0);
294 | for (CalendarBean monthBean : calendars) {
295 | for (DateBean dateBean : monthBean.getDateBeans()) {
296 | if ("今天".equals(dateBean.getShownDay())) {
297 | todayBean = dateBean;
298 | break;
299 | }
300 | }
301 | }
302 | setCalendarEnableRange(todayBean);
303 | } else if (tab.getPosition() == 1) {
304 | if (roundModeDepDate == null) {
305 | // 当去程日期没选时,回程不可点
306 | roundTripTop.getTabAt(0).select();
307 | return;
308 | }
309 | roundModeBackDate = null;
310 | tab.setText("返程");
311 | }
312 | }
313 |
314 | @Override
315 | public void onTabUnselected(TabLayout.Tab tab) {
316 | }
317 |
318 | @Override
319 | public void onTabReselected(TabLayout.Tab tab) {
320 | }
321 | });
322 | } else {
323 | roundTripTop.setVisibility(View.GONE);
324 | }
325 | TextView weekHint;
326 | weekLayout.removeAllViews();
327 | for (int i = 0; i < weeks.length; i++) {
328 | weekHint = new TextView(mContext);
329 | weekHint.setLayoutParams(new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1));
330 | weekHint.setGravity(Gravity.CENTER);
331 | weekHint.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
332 | weekHint.setText(weeks[i]);
333 | if (i == 0 || i == weeks.length - 1) {
334 | //周末-红色
335 | weekHint.setTextColor(Color.parseColor("#D83939"));
336 | } else {
337 | //工作日
338 | weekHint.setTextColor(Color.parseColor("#111111"));
339 | }
340 | weekLayout.addView(weekHint);
341 | }
342 | }
343 |
344 | public void setBarTitle(String newTitle) {
345 | barTitle.setText(newTitle);
346 | }
347 |
348 | public void setBarBack(boolean need) {
349 | if (need) {
350 | getSupportActionBar().setDisplayHomeAsUpEnabled(true);
351 | } else {
352 | getSupportActionBar().setDisplayHomeAsUpEnabled(false);
353 | }
354 | }
355 |
356 | private void initPrice() {
357 | priceMap.put("2018-07-11", "360");
358 | priceMap.put("2018-07-12", "370");
359 | priceMap.put("2018-07-13", "310");
360 | priceMap.put("2018-07-14", "380");
361 | priceMap.put("2018-07-15", "250");
362 | priceMap.put("2018-07-16", "330");
363 | priceMap.put("2018-07-17", "460");
364 | priceMap.put("2018-07-18", "460");
365 | priceMap.put("2018-07-19", "470");
366 | priceMap.put("2018-07-20", "440");
367 | priceMap.put("2018-07-21", "410");
368 | priceMap.put("2018-07-22", "550");
369 | priceMap.put("2018-07-23", "250");
370 | priceMap.put("2018-07-24", "520");
371 |
372 | new ThreadPoolProxy().executeTaskDelay(new Runnable() {
373 | @Override
374 | public void run() {
375 | runOnUiThread(new Runnable() {
376 | @Override
377 | public void run() {
378 | groupAdatper.updateForPrice(priceMap);
379 | }
380 | });
381 | }
382 | }, 1000);
383 | }
384 |
385 | private DateBean roundModeDepDate;
386 | private DateBean roundModeBackDate;
387 |
388 | @Override
389 | public void onDaySelect(DateBean bean) {
390 | if (pickerMode == MODE.SINGLE.toNumber()) {
391 | // 单程
392 | Intent intent = new Intent();
393 | intent.putExtra("resultDate", bean);
394 | setResult(RESULT_OK, intent);
395 | finish();
396 | return;
397 | }
398 | if (roundTripTop.getSelectedTabPosition() == 0) {
399 | roundModeDepDate = bean;
400 | roundTripTop.getTabAt(0).setText("去程\n" + roundModeDepDate.getFomartTag());
401 | roundTripTop.getTabAt(1).select();
402 | } else {
403 | roundModeBackDate = bean;
404 | roundTripTop.getTabAt(1).setText("返程\n" + roundModeBackDate.getFomartTag());
405 | if (roundModeDepDate != null && roundModeBackDate != null) {
406 | mHandler.postDelayed(new Runnable() {
407 | @Override
408 | public void run() {
409 | Intent intent = new Intent();
410 | intent.putExtra("resultDate", roundModeDepDate);
411 | intent.putExtra("resultDate_back", roundModeBackDate);
412 | setResult(RESULT_OK, intent);
413 | finish();
414 | }
415 | }, 400);
416 | } else {
417 | ToastUtils.showShort("请选择一个日期");
418 | }
419 | return;
420 | }
421 | setCalendarEnableRange(bean);
422 | }
423 |
424 | /**
425 | * 设置日历可选范围
426 | *
427 | * @param centerBean 临界日期
428 | */
429 | private void setCalendarEnableRange(DateBean centerBean) {
430 | for (CalendarBean monthBean : calendars) {
431 | for (DateBean dateBean : monthBean.getDateBeans()) {
432 | // if (dateBean.getFomartTag().equals(centerBean.getFomartTag())) {
433 | // dateBean.setCheck(true);
434 | // } else {
435 | // dateBean.setCheck(false);
436 | // }
437 | if (dateBean.getSaverCalendar() != null) {
438 | if (dateBean.getSaverCalendar().before(centerBean.getSaverCalendar())) {
439 | dateBean.setCanSelect(false);
440 | } else {
441 | dateBean.setCanSelect(true);
442 | }
443 | } else {
444 | dateBean.setCanSelect(false);
445 | }
446 |
447 | }
448 | }
449 | groupAdatper.notifyDataSetChanged();
450 | ((LinearLayoutManager) recyclerView.getLayoutManager()).scrollToPositionWithOffset(
451 | centerBean.getGroupIndex(), 0);
452 | }
453 |
454 |
455 | public static class RecyclerAdapter extends RecyclerView.Adapter {
456 |
457 | private final static int TYPE_CONTENT = 1;
458 |
459 | private List results = new ArrayList<>();
460 | private HashMap priceMap = new HashMap<>();
461 | private CalendarListener calendarListener;
462 |
463 | public RecyclerAdapter(List results, CalendarListener calendarListener) {
464 | this.results = results;
465 | this.calendarListener = calendarListener;
466 | }
467 |
468 | public void updateForPrice(HashMap priceMap) {
469 | this.priceMap = priceMap;
470 | notifyDataSetChanged();
471 | }
472 |
473 | @Override
474 | public int getItemViewType(int position) {
475 | return TYPE_CONTENT;
476 | }
477 |
478 | @Override
479 | public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
480 | View view = LayoutInflater.from(mContext).inflate(R.layout.calendar_group_item, parent, false);
481 | return new CalendarViewHolder(view);
482 | }
483 |
484 | @Override
485 | public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
486 | initItemView(holder, position, results.get(position));
487 | }
488 |
489 | @Override
490 | public int getItemCount() {
491 | return results != null ? (results.size()) : 0;
492 | }
493 |
494 | private void initItemView(RecyclerView.ViewHolder holder, int position, CalendarBean bean) {
495 | CalendarViewHolder calendarViewHolder = (CalendarViewHolder) holder;
496 | calendarViewHolder.mTitle.setText(bean.getShownTitle());
497 | calendarViewHolder.subAdapter.showResult(bean.getDateBeans(), priceMap);
498 | }
499 |
500 | class CalendarViewHolder extends RecyclerView.ViewHolder {
501 |
502 | TextView mTitle;
503 | RecyclerView recyclerView;
504 | SubRecyclerAdapter subAdapter;
505 | List subResults = new ArrayList<>();
506 |
507 | public CalendarViewHolder(View itemView) {
508 | super(itemView);
509 | mTitle = (TextView) itemView.findViewById(R.id.month_title);
510 | recyclerView = (RecyclerView) itemView.findViewById(R.id.month_recycler);
511 | GridLayoutManager gridLayoutManager = new GridLayoutManager(mContext, 7);
512 | recyclerView.setLayoutManager(gridLayoutManager);
513 | subAdapter = new SubRecyclerAdapter(subResults, calendarListener);
514 | recyclerView.setAdapter(subAdapter);
515 | }
516 | }
517 | }
518 |
519 |
520 | public static class SubRecyclerAdapter extends RecyclerView.Adapter {
521 |
522 | private List results = new ArrayList<>();
523 | private HashMap priceMap = new HashMap<>();
524 | private CalendarListener calendarListener;
525 |
526 | public SubRecyclerAdapter(List results, CalendarListener calendarListener) {
527 | this.results = results;
528 | this.calendarListener = calendarListener;
529 | }
530 |
531 | public void showResult(List results, HashMap priceMap) {
532 | this.results = results;
533 | this.priceMap = priceMap;
534 | notifyDataSetChanged();
535 | }
536 |
537 | @Override
538 | public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
539 | View view = LayoutInflater.from(mContext).inflate(R.layout.calendar_child_item, parent, false);
540 | return new SubCalendarViewHolder(view);
541 | }
542 |
543 | @Override
544 | public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
545 | initItemView(holder, position, results.get(position));
546 | }
547 |
548 | @Override
549 | public int getItemCount() {
550 | return results != null ? (results.size()) : 0;
551 | }
552 |
553 | private void initItemView(RecyclerView.ViewHolder holder, int position, final DateBean bean) {
554 | final SubCalendarViewHolder subCalendarViewHolder = (SubCalendarViewHolder) holder;
555 | subCalendarViewHolder.mDay.setText(bean.getShownDay());
556 | if (priceMap != null && !TextUtils.isEmpty(priceMap.get(bean.getFomartTag()))) {
557 | subCalendarViewHolder.mSubDay.setText("¥" + priceMap.get(bean.getFomartTag()));
558 | } else if (!TextUtils.isEmpty(bean.getSpecialDayTag())) {
559 | subCalendarViewHolder.mSubDay.setText(bean.getSpecialDayTag());
560 | } else {
561 | subCalendarViewHolder.mSubDay.setText(bean.getNongliDay());
562 | }
563 | // 法定节假日默认隐藏
564 | subCalendarViewHolder.mGovHolidayHint.setVisibility(View.INVISIBLE);
565 | if (!bean.isCanSelect()) {
566 | // 不可选
567 | subCalendarViewHolder.mDay.setTextColor(Color.parseColor("#D5D5D5"));
568 | } else if (bean.isGovHoliday()) {
569 | // 节假日
570 | subCalendarViewHolder.mGovHolidayHint.setVisibility(View.VISIBLE);
571 | subCalendarViewHolder.mGovHolidayHint.setText("休");
572 | subCalendarViewHolder.mGovHolidayHint.setTextColor(Color.parseColor("#D83939"));
573 | subCalendarViewHolder.mDay.setTextColor(Color.parseColor("#D83939"));
574 | } else if (bean.isGovHolidayWork()) {
575 | // 调休工作日
576 | subCalendarViewHolder.mGovHolidayHint.setVisibility(View.VISIBLE);
577 | subCalendarViewHolder.mGovHolidayHint.setText("班");
578 | subCalendarViewHolder.mGovHolidayHint.setTextColor(Color.parseColor("#111111"));
579 | subCalendarViewHolder.mDay.setTextColor(Color.parseColor("#111111"));
580 | } else if (bean.getDayOfWeek() == 1 || bean.getDayOfWeek() == 7) {
581 | //正常周末
582 | subCalendarViewHolder.mDay.setTextColor(Color.parseColor("#D83939"));
583 | } else {
584 | //其他工作日
585 | subCalendarViewHolder.mDay.setTextColor(Color.parseColor("#111111"));
586 | }
587 | if (bean.isCheck()) {
588 | //选中 blue
589 | subCalendarViewHolder.itemView.setBackgroundResource(R.drawable.calendar_check_bg);
590 | } else {
591 | subCalendarViewHolder.itemView.setBackgroundColor(Color.parseColor("#00000000"));
592 | }
593 | subCalendarViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
594 | @Override
595 | public void onClick(View v) {
596 | if (bean.isCanSelect()) {
597 | calendarListener.onDaySelect(bean);
598 | }
599 | }
600 | });
601 | }
602 |
603 | static class SubCalendarViewHolder extends RecyclerView.ViewHolder {
604 |
605 | TextView mDay;
606 | TextView mSubDay;
607 | TextView mGovHolidayHint;
608 |
609 | public SubCalendarViewHolder(View itemView) {
610 | super(itemView);
611 | mDay = (TextView) itemView.findViewById(R.id.day);
612 | mSubDay = (TextView) itemView.findViewById(R.id.subday);
613 | mGovHolidayHint = (TextView) itemView.findViewById(R.id.gov_holiday_hint);
614 | }
615 | }
616 | }
617 |
618 | @Override
619 | public boolean onOptionsItemSelected(MenuItem item) {
620 | switch (item.getItemId()) {
621 | case android.R.id.home:
622 | finish();
623 | return true;
624 | default:
625 | break;
626 | }
627 | return super.onOptionsItemSelected(item);
628 | }
629 | }
630 |
--------------------------------------------------------------------------------