Demo地址:https://download.youkuaiyun.com/download/m13984458297/11021700
功能:能查看上一个月、下一个月、上一年、下一年的日期;点击每天能获取当天的具体时间,底部显示的是当天的具体信息,当然我只提供一个最基本的功能,其他的课根据自己的需求来优化。
效果图如下:
核心类,也是GridView的适配器CalendarAdapter(类中涉及的颜色值,图片文件等自己提供):
package cn.longmaster.hospital.doctor.ui.user;
import android.content.Context;
import android.graphics.Color;
import android.util.ArraySet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import java.text.SimpleDateFormat;
import java.util.Set;
import cn.longmaster.hospital.doctor.R;
import cn.longmaster.hospital.doctor.view.timetable.SpecialCalendar;
/**
* Created by W·H·K on 2019/3/8.
*/
public class CalendarAdapter extends BaseAdapter {
private static String TAG = "CalendarAdapter";
private boolean isLeapyear = false; //是否为闰年
private int daysOfMonth = 0;//某月的天数
private int dayOfWeek = 0;//具体某一天是星期几
private int lastDaysOfMonth = 0; //上一个月的总天
private Context context;
private String[] dayNumber = new String[42]; //一个gridview中的日期存入此数组中
private SpecialCalendar sc = null;
private int currentYear = 0;
private int currentMonth = 0;
private int currentFlag = -1;
/**
* * 当前选中天的字符串 例:20170830
*
*/
private String currentDayStr;
private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-M-d");
private Set<Integer> schDateTagFlag = new ArraySet<>(); //存储当月所有的日程日期(标签)
private String showYear = "";
//用于在头部显示的年份
private String showMonth = ""; //用于在头部显示的月份
private String animalsYear = "";
private String leapMonth = "";
//闰哪一个月
private Set<String> mSet = null;
/**
* * 距离当前月的差(上一个月-1,当前月0,下一个月+1)
*
*/
private OnItemClickListener mOnItemClickListener;
public CalendarAdapter(Context context, long time) {
this.context = context;
sc = new SpecialCalendar();
int year = Integer.valueOf(sc.LongToString(time, "yyyy")).intValue();
currentYear = year;
int month = Integer.valueOf(sc.LongToString(time, "MM")).intValue();
currentMonth = month; //得到跳转到的月份
this.currentDayStr = sc.LongToString(time, "yyyy-MM-dd");
getCalendar(currentYear, currentMonth);
}
public void setOnItemClickListener(OnItemClickListener listener) {
mOnItemClickListener = listener;
}
@Override
public int getCount() {
return dayNumber.length;
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder myViewHolder = null;
if (convertView == null || convertView.getTag() == null) {
myViewHolder = new ViewHolder();
convertView = LayoutInflater.from(context).inflate(R.layout.item_select_time, null);
myViewHolder.mIdTvItemSelectTimeDay = (TextView) convertView.findViewById(R.id.id_tv_item_select_time_day);
myViewHolder.itemView = convertView.findViewById(R.id.item_view);
convertView.setTag(myViewHolder);
} else {
myViewHolder = (ViewHolder) convertView.getTag();
}
displayView(myViewHolder, position);
return convertView;
}
private void displayView(final ViewHolder myViewHolder, final int position) {
myViewHolder.mIdTvItemSelectTimeDay.setText(dayNumber[position]);
myViewHolder.mIdTvItemSelectTimeDay.setBackgroundColor(Color.WHITE);//不是当前月为灰
myViewHolder.mIdTvItemSelectTimeDay.setTextColor(context.getColor(R.color.color_cccccc));//不是当前月为灰
if (position < daysOfMonth + dayOfWeek && position >= dayOfWeek) {
// 当前月信息显示
myViewHolder.mIdTvItemSelectTimeDay.setTextColor(context.getColor(R.color.color_1a1a1a));// 当月字体设黑
myViewHolder.mIdTvItemSelectTimeDay.setTag(true);// 当月字体设黑
if (getItemTime(position).equals("2019年03月05") || getItemTime(position).equals("2019年03月18") || getItemTime(position).equals("2019年03月22")) {
myViewHolder.mIdTvItemSelectTimeDay.setBackground(context.getDrawable(R.drawable.bg_course_can_appointment));
myViewHolder.mIdTvItemSelectTimeDay.setTextColor(Color.WHITE);
myViewHolder.mIdTvItemSelectTimeDay.setTag(1);
} else if (getItemTime(position).equals("2019年03月07") || getItemTime(position).equals("2019年03月10") || getItemTime(position).equals("2019年03月28")) {
myViewHolder.mIdTvItemSelectTimeDay.setBackground(context.getDrawable(R.drawable.bg_course_not_can_appointment));
myViewHolder.mIdTvItemSelectTimeDay.setTag(2);
} else {
myViewHolder.mIdTvItemSelectTimeDay.setBackgroundColor(Color.WHITE);
myViewHolder.mIdTvItemSelectTimeDay.setTag(0);
}
} else {
myViewHolder.mIdTvItemSelectTimeDay.setTag(false);// 当月字体设黑
}
if (currentFlag != -1 && currentFlag == position) {
//设置当天的背景
myViewHolder.mIdTvItemSelectTimeDay.setBackgroundResource(R.color.color_eeeeee);
//myViewHolder.mIdTvItemSelectTimeDay.setTextColor(Color.WHITE);
}
myViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (position < daysOfMonth + dayOfWeek && position >= dayOfWeek) {
/* myViewHolder.mIdTvItemSelectTimeDay.setBackground(context.getDrawable(R.drawable.bg_course_can_appointment));
myViewHolder.mIdTvItemSelectTimeDay.setTextColor(Color.WHITE);*/
if (mOnItemClickListener != null) {
mOnItemClickListener.onItemClick(view, position);
}
}
}
});
}
/**
* * 更新日历数据
*
*/
public void upData(int stepYear, int stepMonth) {
getCalendar(stepYear, stepMonth);
}
/**
* * 得到某年的某月的天数且这月的第一天是星期几
* *
* * @param year
* * @param month
*
*/
private void getCalendar(int year, int month) {
isLeapyear = sc.isLeapYear(year);//是否为闰年
daysOfMonth = sc.getDaysOfMonth(isLeapyear, month); //某月的总天数
dayOfWeek = sc.getWeekdayOfMonth(year, month);//某月第一天为星期几
lastDaysOfMonth = sc.getDaysOfMonth(isLeapyear, month - 1); //上一个月的总天数
getWeek(year, month);
}
/**
* * 将一个月中的每一天的值添加入数组dayNuber中
* *
* * @param year
* * @param month
*
*/
private void getWeek(int year, int month) {
schDateTagFlag.clear();
currentFlag = -1;
int j = 1;
//得到当前月的所有日程日期(这些日期需要标记)
for (int i = 0; i < dayNumber.length; i++) {
if (i < dayOfWeek) { //前一个月
int temp = lastDaysOfMonth - dayOfWeek + 1;
dayNumber[i] = (temp + i) + "";
} else if (i < daysOfMonth + dayOfWeek) {//本月
int day = i - dayOfWeek + 1; //得到的日期
dayNumber[i] = i - dayOfWeek + 1 + "";
//对于当前月才去标记当前日期
String yearStr = String.valueOf(year);
String monthStr = getStr(String.valueOf(month), 2);
String dayStr = getStr(String.valueOf(day), 2);
String timeAll = yearStr + "-" + monthStr + "-" + dayStr;
if (timeAll.equals(currentDayStr)) {//判断选中的位置
currentFlag = i;
}
if (mSet != null && mSet.size() > 0) {
for (String s : mSet) {//迭代器遍历判断是否需要带标签
if (timeAll.equals(s)) {
schDateTagFlag.add(i);
}
}
}
setShowYear(yearStr);
setShowMonth(String.valueOf(month));
} else { //下一个月
dayNumber[i] = j + "";
j++;
}
}
}
/**
* * 获取当前时间 样式:20170830
* * @param position
* * @return
*
*/
public String getItemTime(int position) {
String month = getStr(getShowMonth(), 2);
String day = getStr(getDateByClickItem(position), 2);
return getShowYear() + "年" + month + "月" + day;
}
/**
* * 保留N位整数,不足前面补0
* *
* * @param file String
* * @param bit 位数
* * @return
*
*/
public static String getStr(String file, int bit) {
while (file.length() < bit)
file = "0" + file;
return file;
}
/**
* * 点击每一个item时返回item中的日期
* *
* * @param position
* * @return
*
*/
public String getDateByClickItem(int position) {
return dayNumber[position];
}
/**
* * 在点击gridView时,得到这个月中第一天的位置
* *
* * @return
*
*/
public int getStartPositon() {
return dayOfWeek + 7;
}
/**
* * 在点击gridView时,得到这个月中最后一天的位置
* *
* * @return
*
*/
public int getEndPosition() {
return (dayOfWeek + daysOfMonth + 7) - 1;
}
public String getShowYear() {
return showYear;
}
public void setShowYear(String showYear) {
this.showYear = showYear;
}
public String getShowMonth() {
return showMonth;
}
public void setShowMonth(String showMonth) {
this.showMonth = showMonth;
}
public String getAnimalsYear() {
return animalsYear;
}
public void setAnimalsYear(String animalsYear) {
this.animalsYear = animalsYear;
}
public String getLeapMonth() {
return leapMonth;
}
public void setLeapMonth(String leapMonth) {
this.leapMonth = leapMonth;
}
public Set<String> getSet() {
return mSet;
}
public void setSet(Set<String> set) {
mSet = set;
}
class ViewHolder {
TextView mIdTvItemSelectTimeDay;
View itemView;
}
interface OnItemClickListener {
void onItemClick(View view, int position);
}
}
2、item布局文件item_select_time:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/item_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="5dp"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/id_tv_item_select_time_day"
android:layout_width="25dp"
android:layout_height="25dp"
android:background="@drawable/bg_course_can_appointment"
android:gravity="center"
android:text="天"
android:textSize="14sp"
android:textStyle="bold" />
</LinearLayout>
</RelativeLayout>
最后就是在activity中使用了:
我的思路是,不管点击是上一年、下一年、上一个月、下一个月之前都会取出当前的时间,格式为:yyyy年MM月dd,
然后(mTitleDateTv为顶部的TextView):
private final String FORMAT_TYPE = "yyyy年MM月dd";
mAdapter = new CalendarAdapter(this, mCurrentTime);//mCurrentTime为当前时间的龙类型数据 gridView.setAdapter(mAdapter);/** * 上一年 */ private void displayLastYearView() { long tempTime = SpecialCalendar.StringToLong(mTitleDateTv.getText().toString().trim(), FORMAT_TYPE); int year = Integer.valueOf(SpecialCalendar.LongToString(tempTime, "yyyy")).intValue() - 1; int month = Integer.valueOf(SpecialCalendar.LongToString(tempTime, "MM")).intValue(); int day = Integer.valueOf(SpecialCalendar.LongToString(tempTime, "dd")).intValue(); Logger.logI(Logger.APPOINTMENT, "CourseTableActivity-->displayNextYear->year:" + year + ",month:" + month + ",day:" + day); upDateData(year, month, day); }
/**
* 下一年
*/
private void displayNextYear() {
long tempTime = SpecialCalendar.StringToLong(mTitleDateTv.getText().toString().trim(), FORMAT_TYPE);
int year = Integer.valueOf(SpecialCalendar.LongToString(tempTime, "yyyy")).intValue() + 1;
int month = Integer.valueOf(SpecialCalendar.LongToString(tempTime, "MM")).intValue();
int day = Integer.valueOf(SpecialCalendar.LongToString(tempTime, "dd")).intValue();
upDateData(year, month, day);
}
/**
* 上一个月
*/
private void displayLastMonthView() {
long tempTime = SpecialCalendar.StringToLong(mTitleDateTv.getText().toString().trim(), FORMAT_TYPE);
int year = Integer.valueOf(SpecialCalendar.LongToString(tempTime, "yyyy")).intValue();
int month = Integer.valueOf(SpecialCalendar.LongToString(tempTime, "MM")).intValue() - 1;
int day = Integer.valueOf(SpecialCalendar.LongToString(tempTime, "dd")).intValue();
if (month == 0) {
year = year - 1;
month = 12;
}
upDateData(year, month, day);
}
/**
* 下一个月
*/
private void displayNextMonth() {
long tempTime = SpecialCalendar.StringToLong(mTitleDateTv.getText().toString().trim(), FORMAT_TYPE);
int year = Integer.valueOf(SpecialCalendar.LongToString(tempTime, "yyyy")).intValue();
int month = Integer.valueOf(SpecialCalendar.LongToString(tempTime, "MM")).intValue() + 1;
int day = Integer.valueOf(SpecialCalendar.LongToString(tempTime, "dd")).intValue();
if (month > 12) {
year = year + 1;
month = 1;
}
upDateData(year, month, day);
}
private void upDateData(int year, int month, int day) {
mAdapter.upData(year, month);
mAdapter.notifyDataSetChanged();
}
提供下时间工具类:SpecialCalendar
package cn.longmaster.hospital.doctor.view.timetable;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
/**
* * 日历工具类
*
*/
public class SpecialCalendar {
private int daysOfMonth = 0;//某月的天数
private int dayOfWeek = 0;//具体某一天是星期几
/**
* * 判断是否为闰年
* * @param year
* * @return
*
*/
public boolean isLeapYear(int year) {
if (year % 100 == 0 && year % 400 == 0) {
return true;
} else if (year % 100 != 0 && year % 4 == 0) {
return true;
}
return false;
}
/**
* * 得到某月有多少天数
* * @param isLeapyear
* * @param month
* * @return
*
*/
public int getDaysOfMonth(boolean isLeapyear, int month) {
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
daysOfMonth = 31;
break;
case 4:
case 6:
case 9:
case 11:
daysOfMonth = 30;
break;
case 2:
if (isLeapyear) {
daysOfMonth = 29;
} else {
daysOfMonth = 28;
}
}
return daysOfMonth;
}
/**
* * 指定某年中的某月的第一天是星期几
* * @param year
* * @param month
* * @return
*
*/
public int getWeekdayOfMonth(int year, int month) {
Calendar cal = Calendar.getInstance();
cal.set(year, month - 1, 1);
dayOfWeek = cal.get(Calendar.DAY_OF_WEEK) - 1;
return dayOfWeek;
}
/**
* 时间string转long
*
* @param time
* @param formatType
* @return
*/
public static long StringToLong(String time, String formatType) {
if (time != null) {
Date date = StringToDate(time, formatType);
return date.getTime();
}
return 0;
}
/**
* 时long转string
*
* @param num
* @param formatType
* @return
*/
public static String LongToString(long num, String formatType) {
Date date = LongToDate(num);
return DateToString(date, formatType);
}
/**
* 时间String转Date
*
* @param time
* @param formatType
* @return
*/
public static Date StringToDate(String time, String formatType) {
SimpleDateFormat formatter = new SimpleDateFormat(formatType);
Date date = null;
try {
if (time != null) {
date = formatter.parse(time);
}
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
/**
* 时间LongToDate
*
* @param num
* @return
*/
public static Date LongToDate(long num) {
Date date = new Date(num);
return date;
}
/**
* 时间DateToString
*
* @param date
* @param formatType
* @return
*/
public static String DateToString(Date date, String formatType) {
if (date != null) {
return new SimpleDateFormat(formatType).format(date);
}
return null;
}
/**
* 时间DateToLong
*
* @param date
* @return
*/
public static long DateToLong(Date date) {
if (date != null) {
return date.getTime();
}
return 0;
}
/**
* 下个或上个月
*
* @param date
* @return
*/
public static String getMonth(Date date, int i) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + i);
Date time = calendar.getTime();
return DateToString(time, "yyyy年MM月dd");
}
/**
* 获取星期
*/
public static String getWeek(Date date) {
String[] weeks = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
Calendar cal = Calendar.getInstance();
cal.setTime(date);
int week_index = cal.get(Calendar.DAY_OF_WEEK) - 1;
if (week_index < 0) {
week_index = 0;
}
return weeks[week_index];
}
/**
* * 保留N位整数,不足前面补0
* *
* * @param file String
* * @param bit 位数
* * @return
*
*/
public static String getBitStr(String file, int bit) {
while (file.length() < bit)
file = "0" + file;
return file;
}
}