安卓多选日期日历控件

时间:2022-09-03 00:22:14


        需求是这样的:在日历控件中,每一个日期都有选择和取消两种状态,也就是说每个日期的控件相当于复选框。被选择的日期列表可以获得。也可以设定选择好的列表日期到控件中。其实看起来挺简单的,其实就是把安卓的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;

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;
}
}
          适配器把一个月的日期列表适配到gridview中,并把 日期选择 标记到的,进行选择确定。其中CustomCalendarView  就是下面要说自定义的calendar的view。calendarveiw有存放日期选择的选择列表。

        4、

    

package com.xiaoyunchengzhu.multiselectcalendarview.customview;

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);
}
}
        一个gridview展示的是一个月的日期日历,以及这个月是否被选中的日期的标记。每个月的1号是    从星期几开始的,这个月一共有多少天,都需要计算,还有添加到日期列表中。

      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