# 实现思路概述
> 由于我学 `Java` 是**半路出家,所以一些东西讲的并不标准**,请见谅,很愿意接受大家的批评建议
1. 用一个集合(`List`) 储存本页日历的日期信息(年、月、日、是否为本月)
2. 实例化日历类 `Calendar`
```
Calendar calendar = Calendar.getInstance();
```
3. 设置要显示哪年哪月的日历信息
```
calendar.set(Calendar.YEAR, 2020);//设置哪年
calendar.set(Calendar.MONTH, 11);//设置哪个月
```
4. 将日历信息设置为本月1号
```
calendar.set(Calendar.DAY_OF_MONTH, 1);//将日期推到本月1号
```
5. 获取本月1号是星期几,**由于我们需要设置从 周一 为一周的开始**,所以就有以下代码
> 如果是星期一,变量 `currentDayOfWeek` 应该输出 1;
> ...
> 如果是星期日,变量 `currentDayOfWeek` 应该输出 7.
```
int currentDayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
currentDayOfWeek = currentDayOfWeek == 1
? 7 : currentDayOfWeek - 1;//获取当前星期几(星期一就是1 ... 星期天是 7)
```
6. 按照习惯,除了显示本月日历,一般还会显示上个月或下个月来填充 **剩余的格子**,所以我们在绘制前,将日期再往前推(减去) **当前星期几+1 的天数**
> ![按照习惯,除了显示本月日历,一般还会显示上个月或下个月来填充 **剩余的格子**,所以我们在绘制前,将日期再往前推(减去) 当前星期几+1 的天数][1]
```
calendar.add(Calendar.DATE, -currentDayOfWeek + 1);//将日期倒退 当前星期几+1 的天数
```
7. 然后 **for 循环**,基础的日历格子有 **35** 个
```
for (int i = 0; i < 35; i++) {
Log.i("日期", calendar.get(Calendar.YEAR)+"年"
+calendar.get(Calendar.MONTH) + 1+"月"+calendar.get(Calendar.DAY_OF_MONTH)+"日";
calendar.add(Calendar.DATE, +1);//日期+1 获取明天的
}
```
8. **但是有特殊情况**,当该月1号是 **星期日**,那么我们还应该再增加 `7个格子`,不然日历显示不完整。所以我们需要额外判断下
```
//绘制的格子数,如果恰好本月1号是星期天,那么就还要再加7个格子以显示完整日历
int gridNum = (currentDayOfWeek < 7) ? 35 : 42;
for (int i = 0; i < gridNum; i++) {
Log.i("日期", calendar.get(Calendar.YEAR)+"年"
+calendar.get(Calendar.MONTH) + 1+"月"+calendar.get(Calendar.DAY_OF_MONTH)+"日";
calendar.add(Calendar.DATE, +1);//日期+1 获取明天的
}
```
9. 大概日历的思路就是这样,要用其它语言实现也并不难
# `CalendarBean.java`
```java
public class CalendarBean {
private int year;
private int month;
private int day;
private boolean currentMonth;
private boolean isChecked = false;
public CalendarBean() {
}
public CalendarBean(int year, int month, int day, boolean currentMonth) {
this.year = year;
this.month = month;
this.day = day;
this.currentMonth = currentMonth;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
public int getDay() {
return day;
}
public void setDay(int day) {
this.day = day;
}
public boolean isCurrentMonth() {
return currentMonth;
}
public void setCurrentMonth(boolean currentMonth) {
this.currentMonth = currentMonth;
}
@NonNull
@Override
public String toString() {
return getYear() + "年" + getMonth() + "月" + getDay() + "日";
}
public boolean isChecked() {
return isChecked;
}
public void setChecked(boolean checked) {
isChecked = checked;
}
}
```
# CalendarCreate.java
```java
public class CalendarCreate{
private Calendar calendar;
private ListcalendarBeanList = new ArrayList<>();
public static void main(String[] args){
printCalendar(2020, 11);//输出2020年11月日历
}
public void printCalendar(int year, int month) {
month -= 1;//减去1,因为 java 日历,月份从 0 开始
int currentDayOfWeek;
calendarBeanList.clear();
calendar.set(Calendar.YEAR, year);//设置哪年
calendar.set(Calendar.MONTH, month);//设置哪个月
calendar.set(Calendar.DAY_OF_MONTH, 1);//将日期推到本月1号
currentDayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
currentDayOfWeek = currentDayOfWeek == 1
? 7 : currentDayOfWeek - 1;//获取当前星期几(星期一就是1 ... 星期天是 7)
calendar.add(Calendar.DATE, -currentDayOfWeek + 1);//将日期倒退 当前星期几+1 的天数
int gridNum = (currentDayOfWeek < 7) ? 35 : 42;//绘制的格子数,如果恰好本月1号是星期天,那么就还要再加57个格子以显示完整日历
for (int i = 0; i < gridNum; i++) {
calendarBeanList.add(i, new CalendarBean(
calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH) + 1,//一年中的哪个月。月份
calendar.get(Calendar.DAY_OF_MONTH),//一个月中的第几天。几号
calendar.get(Calendar.MONTH) == month//判断是否为本月
));
calendar.add(Calendar.DATE, +1);//日期+1 获取明天的
}
Log.i("打印日历数组", calendarBeanList.toString());
}
}
```
# 运行结果
```
I/打印日历数组: [2020年10月26日, 2020年10月27日, 2020年10月28日, 2020年10月29日, 2020年10月30日,
2020年10月31日, 2020年11月1日, 2020年11月2日, 2020年11月3日, 2020年11月4日, 2020年11月5日,
2020年11月6日, 2020年11月7日, 2020年11月8日, 2020年11月9日, 2020年11月10日, 2020年11月11日,
2020年11月12日, 2020年11月13日, 2020年11月14日, 2020年11月15日, 2020年11月16日, 2020年11月17日,
2020年11月18日, 2020年11月19日, 2020年11月20日, 2020年11月21日, 2020年11月22日, 2020年11月23日,
2020年11月24日, 2020年11月25日, 2020年11月26日, 2020年11月27日, 2020年11月28日, 2020年11月29日,
2020年11月30日, 2020年12月1日, 2020年12月2日, 2020年12月3日, 2020年12月4日, 2020年12月5日,
2020年12月6日]
```
# 实际应用效果
> 橘黄色方框是实际应用效果
> 如果想要看完整的项目代码,可以查看 **糖疯子** 的代码 https://www.jianshu.com/p/4ae8f56f3bcb
![1604206482003.png][2]
[1]: https://cdn.nowtime.cc/2020/11/01/2694057533.jpg
[2]: https://cdn.nowtime.cc/2020/11/01/2390028636.png