需求是这样的:在日历控件中,每一个日期都有选择和取消两种状态,也就是说每个日期的控件相当于复选框。被选择的日期列表可以获得。也可以设定选择好的列表日期到控件中。其实看起来挺简单的,其实就是把安卓的calendarview的日期单选变成多选,能主动初始化选择项,和取出选择项。但是在实际应用中calendarview实在不能满足各种要求。只好自定义日期日历。如下:
1、 先布局自定义view的界面:
<?xml version="1.0" encoding="utf-8"?>创建日期项类
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_margin="@dimen/activity_vertical_margin">
<ImageButton
android:id="@+id/calendarview_imgbutton_left"
android:layout_marginLeft="@dimen/activity_vertical_margin"
android:src="@mipmap/calendar_month_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/calendarviewtext_month"
android:text="2016年4月"
android:layout_width="wrap_content"
android:layout_weight="1"
android:textSize="22sp"
android:gravity="center"
android:layout_height="match_parent" />
<ImageButton
android:id="@+id/calendarview_imgbutton_right"
android:layout_marginRight="@dimen/activity_vertical_margin"
android:src="@mipmap/calendar_month_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:text="日"
android:layout_width="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:textSize="22sp"
android:layout_height="wrap_content" />
<TextView
android:text="一"
android:layout_width="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:textSize="22sp"
android:layout_height="wrap_content" />
<TextView
android:text="二"
android:layout_width="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:textSize="22sp"
android:layout_height="wrap_content" />
<TextView
android:text="三"
android:layout_width="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:textSize="22sp"
android:layout_height="wrap_content" />
<TextView
android:text="四"
android:layout_width="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:textSize="22sp"
android:layout_height="wrap_content" />
<TextView
android:text="五"
android:layout_width="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:textSize="22sp"
android:layout_height="wrap_content" />
<TextView
android:text="六"
android:layout_width="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:textSize="22sp"
android:layout_height="wrap_content" />
</LinearLayout>
<GridView
android:id="@+id/calendarview_grid_gridview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:numColumns="7"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:stretchMode="columnWidth"
android:layout_margin="10dp"
android:gravity="center"></GridView>
</LinearLayout>
2、
public class DateItem {
private int dateOfMonth=0;
private boolean isselect=false;
private int year;
private int month;
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 getDateOfMonth() {
return dateOfMonth;
}
public void setDateOfMonth(int dateOfMonth) {
this.dateOfMonth = dateOfMonth;
}
public boolean isselect() {
return isselect;
}
public void setIsselect(boolean isselect) {
this.isselect = isselect;
}
}
每一个日期都有年、月、日和是否被选择的标记。
3、创建gridvew的适配器
package com.xiaoyunchengzhu.multiselectcalendarview.adapter;适配器把一个月的日期列表适配到gridview中,并把 日期选择 标记到的,进行选择确定。其中CustomCalendarView 就是下面要说自定义的calendar的view。calendarveiw有存放日期选择的选择列表。
import android.content.Context;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import com.xiaoyunchengzhu.multiselectcalendarview.R;
import com.xiaoyunchengzhu.multiselectcalendarview.bean.DateItem;
import com.xiaoyunchengzhu.multiselectcalendarview.customview.CustomCalendarView;
import com.xiaoyunchengzhu.multiselectcalendarview.util.ConfigUtils;
import java.util.Calendar;
import java.util.List;
/**
*
*/
public class CalendarGridViewAdapter extends BaseAdapter {
private List<DateItem> list;
private Context context;
private CustomCalendarView customCalendarView;
private int itembackgourd;
public CalendarGridViewAdapter(CustomCalendarView customCalendarView,Context context,List<DateItem> list,int itembackgourd){
this.context=context;
this.list=list;
this.itembackgourd=itembackgourd;
this.customCalendarView=customCalendarView;
}
public void setDate(List<DateItem> list){
this.list=list;
notifyDataSetChanged();
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
TextView textView=null;
if (convertView==null){
textView=new TextView(context);
convertView=textView;
}
textView= (TextView) convertView;
textView.setGravity(Gravity.CENTER);
if (list.get(position).isselect()){
if (itembackgourd==-1) {
textView.setBackgroundColor(context.getResources().getColor(R.color.tet_blue));
}else {
textView.setBackgroundResource(itembackgourd);
}
}else {
textView.setBackgroundColor(context.getResources().getColor(R.color.base_bg));
}
textView.setTextSize(22);
if (list.get(position).getDateOfMonth()>0){
final TextView finalTextView = textView;
textView.setText(list.get(position).getDateOfMonth() + "");
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
list.get(position).setIsselect(!list.get(position).isselect());
if (list.get(position).isselect()){
if (itembackgourd==-1) {
finalTextView.setBackgroundColor(context.getResources().getColor(R.color.tet_blue));
}else {
finalTextView.setBackgroundResource(itembackgourd);
}
Calendar calendar=Calendar.getInstance();
calendar.set(list.get(position).getYear(),list.get(position).getMonth(),list.get(position).getDateOfMonth());
customCalendarView.addSelectDate(ConfigUtils.simpleDate(calendar.getTime()));
}else {
finalTextView.setBackgroundColor(context.getResources().getColor(R.color.base_bg));
Calendar calendar=Calendar.getInstance();
calendar.set(list.get(position).getYear(),list.get(position).getMonth(),list.get(position).getDateOfMonth());
customCalendarView.removeSelect(ConfigUtils.simpleDate(calendar.getTime()));
}
}
});
}else {
textView.setBackgroundColor(context.getResources().getColor(R.color.base_bg));
textView.setText("");
}
return convertView;
}
}
4、
package com.xiaoyunchengzhu.multiselectcalendarview.customview;一个gridview展示的是一个月的日期日历,以及这个月是否被选中的日期的标记。每个月的1号是 从星期几开始的,这个月一共有多少天,都需要计算,还有添加到日期列表中。
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.xiaoyunchengzhu.multiselectcalendarview.R;
import com.xiaoyunchengzhu.multiselectcalendarview.adapter.CalendarGridViewAdapter;
import com.xiaoyunchengzhu.multiselectcalendarview.bean.DateItem;
import com.xiaoyunchengzhu.multiselectcalendarview.util.ConfigUtils;
import com.xiaoyunchengzhu.multiselectcalendarview.util.inject.Inject;
import com.xiaoyunchengzhu.multiselectcalendarview.util.inject.ViewInject;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
/**
*
*/
public class CustomCalendarView extends LinearLayout {
@Inject(R.id.calendarview_imgbutton_left)
private ImageButton left;
@Inject(R.id.calendarview_imgbutton_right)
private ImageButton right;
@Inject(R.id.calendarviewtext_month)
private TextView moth;
@Inject(R.id.calendarview_grid_gridview)
private GridView gridView;
private CalendarGridViewAdapter adapter;
private int currentYear,currentMonth;
private List<String> selectdateList=new ArrayList<>();
private List<Date> currentWeekList=new ArrayList<>();
private List<Date> currentUnWeekList=new ArrayList<>();
private int itembackground;
private AttributeSet attrs;
public CustomCalendarView(Context context) {
super(context);
View view= LayoutInflater.from(getContext()).inflate(R.layout.custom_calendarview,null);
ViewInject.inject(this,view);
addView(view);
Calendar calendar=Calendar.getInstance();
calendar.setTime(new Date());
inite(calendar.get(Calendar.YEAR),calendar.get(Calendar.MONTH));
}
public CustomCalendarView(Context context, AttributeSet attrs) {
super(context, attrs);
this.attrs=attrs;
View view= LayoutInflater.from(getContext()).inflate(R.layout.custom_calendarview,null);
ViewInject.inject(this,view);
addView(view);
Calendar calendar=Calendar.getInstance();
calendar.setTime(new Date());
inite(calendar.get(Calendar.YEAR),calendar.get(Calendar.MONTH));
}
public CustomCalendarView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.attrs=attrs;
View view= LayoutInflater.from(getContext()).inflate(R.layout.custom_calendarview,null);
ViewInject.inject(this,view);
addView(view);
Calendar calendar=Calendar.getInstance();
calendar.setTime(new Date());
inite(calendar.get(Calendar.YEAR),calendar.get(Calendar.MONTH));
}
private void inite(int year, int month){
getAttrs(getContext(),attrs);
currentYear=year;
currentMonth=month;
moth.setText(currentYear+"年 "+(currentMonth+1)+"月");
List<DateItem> dateItems=new ArrayList<>();
int firstPostion=getFirstDayWeek(currentYear,currentMonth);
int monthDayNum=getMonthDays(currentYear,currentMonth);
firstPostion--;
for (int i=1;i<=(monthDayNum+firstPostion);i++){
DateItem dateItem=new DateItem();
dateItem.setYear(year);
dateItem.setMonth(month);
if (i>firstPostion){
int dayofmonth=i-firstPostion;
dateItem.setDateOfMonth(dayofmonth);
if (selectdateList!=null&&selectdateList.size()>0) {
for (String date : selectdateList) {
Calendar calendar=Calendar.getInstance();
calendar.setTime(ConfigUtils.simpleDate(date));
if (calendar.get(Calendar.YEAR)==year&&calendar.get(Calendar.MONTH)==month&&calendar.get(Calendar.DAY_OF_MONTH)==dayofmonth){
dateItem.setIsselect(true);
}
}
}
}
dateItems.add(dateItem);
}
if (adapter==null) {
adapter = new CalendarGridViewAdapter(this,getContext(), dateItems,itembackground);
gridView.setAdapter(adapter);
}else {
if (dateItems!=null)
adapter.setDate(dateItems);
}
left.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
setLeftOnclick();
}
});
right.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
setRightOnclick();
}
});
}
public void setOnItemClickListener(AdapterView.OnItemClickListener onitemClicklistnear){
gridView.setOnItemClickListener(onitemClicklistnear);
}
public void swichUnWeekTheMonth(boolean isselect){
for (int i=0;i<gridView.getChildCount();i++) {
DateItem dateItem = (DateItem) adapter.getItem(i);
if (dateItem.getDateOfMonth()!=0&&(i%7!=6&&i%7!=0)) {
if (isselect) {
if (!dateItem.isselect()) {
dateItem.setIsselect(isselect);
Calendar calendar = Calendar.getInstance();
calendar.set(currentYear, currentMonth, dateItem.getDateOfMonth());
TextView textView = (TextView) gridView.getChildAt(i);
textView.setBackgroundColor(getResources().getColor(R.color.tet_blue));
addSelectDate(ConfigUtils.simpleDate(calendar.getTime()));
}
} else {
if (dateItem.isselect()) {
dateItem.setIsselect(!dateItem.isselect());
Calendar calendar = Calendar.getInstance();
calendar.set(currentYear, currentMonth, dateItem.getDateOfMonth());
TextView textView = (TextView) gridView.getChildAt(i);
textView.setBackgroundColor(getResources().getColor(R.color.base_bg));
removeSelect(ConfigUtils.simpleDate(calendar.getTime()));
}
}
}
}
}
public void swichWeekendTheMonth(boolean isselect){
for (int i=0;i<gridView.getChildCount();i++) {
DateItem dateItem = (DateItem) adapter.getItem(i);
if (dateItem.getDateOfMonth()!=0&&(i%7==6||i%7==0)) {
if (isselect) {
if (!dateItem.isselect()) {
dateItem.setIsselect(isselect);
Calendar calendar = Calendar.getInstance();
calendar.set(currentYear, currentMonth, dateItem.getDateOfMonth());
TextView textView = (TextView) gridView.getChildAt(i);
textView.setBackgroundColor(getResources().getColor(R.color.tet_blue));
addSelectDate(ConfigUtils.simpleDate(calendar.getTime()));
}
} else {
if (dateItem.isselect()) {
dateItem.setIsselect(!dateItem.isselect());
Calendar calendar = Calendar.getInstance();
calendar.set(currentYear, currentMonth, dateItem.getDateOfMonth());
TextView textView = (TextView) gridView.getChildAt(i);
textView.setBackgroundColor(getResources().getColor(R.color.base_bg));
removeSelect(ConfigUtils.simpleDate(calendar.getTime()));
}
}
}
}
}
public void setSelect(List<String> selectdateList){
this.selectdateList=selectdateList;
inite(currentYear,currentMonth);
invalidate();
}
public void addSelectDate(String date){
selectdateList.add(date);
invalidate();
}
public void removeSelect(String date){
selectdateList.remove(date);
}
public List<Date> getWeekOfMonthList(){
return currentWeekList;
}
public List<Date> getUnWeekMonthList(){
return currentUnWeekList;
}
public List<String> getSelectdateList(){
return selectdateList;
}
private void setLeftOnclick(){
int cutMonth=(currentMonth-1);
if (cutMonth>=0) {
inite(currentYear,cutMonth);
}else {
int cutYear=currentYear-1;
inite(cutYear--,11);
}
invalidate();
}
private void setRightOnclick(){
int cutMonth=(currentMonth+1);
if (cutMonth<=11) {
inite(currentYear,cutMonth);
}else {
int cutYear=currentYear+1;
inite(cutYear,0);
}
invalidate();
}
public void clearCurrentMonthSelect(){
for (int i=0;i<gridView.getChildCount();i++){
DateItem dateItem= (DateItem) adapter.getItem(i);
if (dateItem.isselect()) {
dateItem.setIsselect(!dateItem.isselect());
Calendar calendar=Calendar.getInstance();
calendar.set(currentYear, currentMonth, dateItem.getDateOfMonth());
TextView textView = (TextView) gridView.getChildAt(i);
textView.setBackgroundColor(getResources().getColor(R.color.base_bg));
removeSelect(ConfigUtils.simpleDate(calendar.getTime()));
}
}
}
private void getAttrs(Context context, AttributeSet attrs) {
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.calendarview);
itembackground=ta.getResourceId(R.styleable.calendarview_item_select_backgroud,-1);
ta.recycle();
}
/**
* 通过年份和月份 得到当月的日子
*/
private int getMonthDays(int year, int month) {
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:
if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)){
return 29;
}else{
return 28;
}
default:
return -1;
}
}
/**
* 返回当前月份1号位于周几
* @param year
* 年份
* @param month
* 月份,传入系统获取的,不需要正常的
* @return
* 日:1 一:2 二:3 三:4 四:5 五:6 六:7
*/
private int getFirstDayWeek(int year, int month){
Calendar calendar = Calendar.getInstance();
calendar.set(year, month, 1);
return calendar.get(Calendar.DAY_OF_WEEK);
}
}
5、主Activity展示:
package com.xiaoyunchengzhu.multiselectcalendarview;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.google.gson.Gson;
import com.xiaoyunchengzhu.multiselectcalendarview.customview.CustomCalendarView;
import com.xiaoyunchengzhu.multiselectcalendarview.util.inject.Inject;
import com.xiaoyunchengzhu.multiselectcalendarview.util.inject.ViewInject;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
@Inject(R.id.calendarview)
private CustomCalendarView calendarView;
@Inject(R.id.showselectbutton)
private Button show;
@Inject(R.id.showselect)
private TextView showtext;
private List<String> initeData;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewInject.inject(this);
initeData=new ArrayList<>();
for (int i=0;i<4;i++){
String data="2016-08-"+(27+i);
initeData.add(data);
}
for (int i=0;i<2;i++){
String data="2016-09-"+(27+i);
initeData.add(data);
}
calendarView.setSelect(initeData);
show.setOnClickListener(this);
}
@Override
public void onClick(View v) {
showtext.setText(new Gson().toJson(calendarView.getSelectdateList()));
}
}
初始化 自定义的日历日期控件,然后模拟已经选择的日期进行初始化选择项。点击按钮展示已经选择的日期到界面。
项目github地址:https://github.com/xiaoyunchengzhu/MultiSelectCalendarView