项目需要进行日历的多选,遂使用**GridView + BaseAdapter
**实现了一个多选日历
项目下载:MultiSelectCalendar.zip
效果图:
布局如下:
background_border.xml
1
2
3
4
5
6
| <?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<stroke
android:width="0.5dp"
android:color="#000" />
</shape>
|
activity_main.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
| <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="周日"
android:textColor="#000"
android:textSize="20dp"
android:textStyle="bold" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="周一"
android:textColor="#000"
android:textSize="20dp"
android:textStyle="bold" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="周二"
android:textColor="#000"
android:textSize="20dp"
android:textStyle="bold" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="周三"
android:textColor="#000"
android:textSize="20dp"
android:textStyle="bold" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="周四"
android:textColor="#000"
android:textSize="20dp"
android:textStyle="bold" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="周五"
android:textColor="#000"
android:textSize="20dp"
android:textStyle="bold" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="周六"
android:textColor="#000"
android:textSize="20dp"
android:textStyle="bold" />
</LinearLayout>
<GridView
android:id="@+id/gridView"
android:layout_width="match_parent"
android:layout_height="300dp"
android:layout_marginTop="8dp"
android:numColumns="7" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="上个月" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="下个月" />
</LinearLayout>
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:text="TextView" />
</LinearLayout>
|
date_item.xml
1
2
3
4
5
6
7
8
9
10
| <?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/background_border"
android:text="31"
android:gravity="center"
android:textSize="20sp">
</TextView>
|
DateItem.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
| public class DateItem {
private String year;
private String month;
private String day;
private boolean isCurrentMonth;
private boolean isChecked;
public String getYear() {
return year;
}
public void setYear(String year) {
this.year = year;
}
public String getMonth() {
return month;
}
public void setMonth(String month) {
this.month = month;
}
public String getDay() {
return day;
}
public void setDay(String day) {
this.day = day;
}
public boolean isCurrentMonth() {
return isCurrentMonth;
}
public void setCurrentMonth(boolean currentMonth) {
isCurrentMonth = currentMonth;
}
public boolean isChecked() {
return isChecked;
}
public void setChecked(boolean checked) {
isChecked = checked;
}
@Override
public String toString() {
return year + "-" + month + "-" + day;
}
}
|
MainActivity.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
| public class MainActivity extends AppCompatActivity {
GridView gridView;
List<DateItem> dateItemList;
DateAdapter dateAdapter;
TextView textView;
StringBuilder sb = new StringBuilder();
Calendar calendar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gridView = findViewById(R.id.gridView);
calendar = Calendar.getInstance();
textView = findViewById(R.id.textView);
textView.setText(sb);
dateItemList = DateUtils.getDateList(calendar);
updateTitle();
dateAdapter = new DateAdapter(this, dateItemList, new OnDateCheckedListener() {
@Override
public void onDateChecked(int position, DateItem dateItem) {
sb.setLength(0);
for (DateItem item : dateAdapter.getCheckedList()) {
sb.append(item.toString())
.append(" ");
}
textView.setText(sb);
}
});
gridView.setAdapter(dateAdapter);
findViewById(R.id.button1).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//上个月
calendar.add(Calendar.MONTH, -1);
dateItemList.clear();
dateItemList.addAll(DateUtils.getDateList(calendar));
dateAdapter.notifyDataSetChanged();
updateTitle();
}
});
findViewById(R.id.button2).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//下个月
calendar.add(Calendar.MONTH, 1);
dateItemList.clear();
dateItemList.addAll(DateUtils.getDateList(calendar));
dateAdapter.notifyDataSetChanged();
updateTitle();
}
});
}
private void updateTitle() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.CHINESE);
setTitle(sdf.format(calendar.getTime()));
}
}
|
DateAdapter.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
| public class DateAdapter extends BaseAdapter {
Context context;
List<DateItem> dateItemList;
List<DateItem> checkedItemList = new ArrayList<>();
OnDateCheckedListener onDateCheckedListener;
public DateAdapter(Context context, List<DateItem> dateItemList, OnDateCheckedListener onDateCheckedListener) {
this.context = context;
this.dateItemList = dateItemList;
this.onDateCheckedListener = onDateCheckedListener;
}
public List<DateItem> getCheckedList() {
return checkedItemList;
}
@Override
public int getCount() {
return dateItemList.size();
}
@Override
public Object getItem(int position) {
return dateItemList.get(position);
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
TextView textView = null;
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.date_item, null, false);
}
textView = (TextView) convertView;
final DateItem dateItem = (DateItem) getItem(position);
textView.setText(dateItem.getDay());
textView.setTextColor(dateItem.isCurrentMonth() ? Color.BLACK : Color.GRAY);
if (dateItem.isChecked()) {
textView.setBackgroundColor(Color.RED);
} else {
textView.setBackgroundResource(R.drawable.background_border);
}
if (dateItem.isCurrentMonth()) {
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (dateItem.isChecked()) {
dateItem.setChecked(false);
checkedItemList.remove(dateItem);
} else {
dateItem.setChecked(true);
checkedItemList.add(dateItem);
}
onDateCheckedListener.onDateChecked(position, dateItem);
notifyDataSetChanged();
}
});
} else {
textView.setOnClickListener(null);
}
return convertView;
}
}
|
DateUtils.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
public class DateUtils {
public static List<DateItem> getDateList(Calendar calendar) {
List<DateItem> list = new ArrayList<>();
//今天是星期几
//1-Sunday 2-Monday ... 7-Saturday
int today = calendar.get(Calendar.DAY_OF_MONTH);
//每个月的第一天是星期几,将日期设置为1号进行获取
calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), 1);
int startIndex = calendar.get(Calendar.DAY_OF_WEEK) - 1;
//每个月有多少天
int totalDays = countDaysOfMonth(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH));
//一行有7个日期
//当前月份的第一天索引为startIndex
String year = String.valueOf(calendar.get(Calendar.YEAR));
String month = String.valueOf(calendar.get(Calendar.MONTH));
//将0到startIndex的日期设置为空
for (int i = 0; i < startIndex; i++) {
DateItem dateItem = new DateItem();
dateItem.setCurrentMonth(false);
dateItem.setDay("");
dateItem.setYear(year);
dateItem.setMonth(month);
list.add(dateItem);
}
//添加当前月份
for (int i = 1; i <= totalDays; i++) {
DateItem dateItem = new DateItem();
dateItem.setYear(year);
dateItem.setMonth(month);
dateItem.setDay(String.valueOf(i));
dateItem.setCurrentMonth(true);
list.add(dateItem);
}
//最后需要填充的日期数量为 7 减去 totalDays + startIndex 除以 7 的余数
int c = (7 - (totalDays + startIndex) % 7);
if (c == 7) c = 0;
for (int i = 0; i < c; i++) {
DateItem dateItem = new DateItem();
dateItem.setCurrentMonth(false);
dateItem.setYear(year);
dateItem.setDay("");
dateItem.setMonth(month);
list.add(dateItem);
}
return list;
}
//计算这个月有多少天
private static int countDaysOfMonth(int year, int month) {
switch (++month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
return 31;
case 4:
case 6:
case 9:
case 11:
return 30;
case 2:
return (year % 4 == 0 && year % 100 != 0) ? 29 : 28;
default:
return 0;
}
}
}
|