Android自定义日历控件
版权声明:本文为博主原创文章,未经博主允许不得转载。
好久没有更新博客了,今天给大家带来一个日历控件的示例。先看一下效果图:
首先我们分析一下上图:
(1)、绘制星期的自定义View,用于标识日期的礼拜。
(2)、绘制日期的自定义View。
通过分析我们可以得到日历控件的需求
实现星期View
这里我们直接编写一个week_calendar.xml文件,从星期日开始到星期六。然后在添加到日历控件的顶部 如图
绘制日期的自定义View
我们先创建CalendarBean累来存放日期数据包含年、月、日和星期等,然后获取一个月中的日期的集合
//获取一月中的集合
public static List<CalendarBean> getMonthOfDayList(int y, int m) {
String key=y+""+m;
if(cache.containsKey(key)){
List<CalendarBean> list=cache.get(key);
if(list==null){
cache.remove(key);
}else{
return list;
}
}
List<CalendarBean> list = new ArrayList<CalendarBean>();
cache.put(key,list);
//计算出一月第一天是星期几
int fweek = getDayOfWeek(y, m, 1);
int total = CalendarUtil.getDayOfMaonth(y, m);
//根据星期推出前面还有几个显示
for (int i = fweek - 1; i > 0; i--) {
CalendarBean bean = geCalendarBean(y, m, 1 - i);
bean.mothFlag = -1;
list.add(bean);
}
//获取当月的天数
for (int i = 0; i < total; i++) {
CalendarBean bean = geCalendarBean(y, m, i + 1);
list.add(bean);
}
//为了塞满42个格子,显示多出当月的天数
for (int i = 0; i < 42 - (fweek - 1) - total; i++) {
CalendarBean bean = geCalendarBean(y, m, total + i + 1);
bean.mothFlag = 1;
list.add(bean);
}
return list;
}
然后在控件对应的位置显示出日期
private void setItem() {
selectPostion = -1;
View childAt = getChildAt(0);
//设置顶部星期视图
View view1 = LayoutInflater.from(getContext()).inflate(R.layout.week_calendar, null);
ViewGroup.LayoutParams params2 = new ViewGroup.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, px(48));
view1.setLayoutParams(params2);
if(childAt == null || childAt != view1){
addViewInLayout(view1, 0, view1.getLayoutParams(), true);
}
List<String> stars1 = new ArrayList<String>();
CalendarBean cb = data.get(10);
for (String star : stars){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
Date date = sdf.parse(star);
int[] ymd = CalendarUtil.getYMD(date);
if(cb.year == ymd[0] && cb.moth == ymd[1]){
stars1.add(star);
}
} catch (ParseException e) {
e.printStackTrace();
}
}
for (int i = 0; i < data.size(); i++) {
for (String star : stars1){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
Date date = sdf.parse(star);
int[] ymd = CalendarUtil.getYMD(date);
if(data.get(i).year == ymd[0] && data.get(i).moth == ymd[1] && data.get(i).day == ymd[2]){
data.get(i).hasEvent = true;
}
} catch (ParseException e) {
e.printStackTrace();
}
}
}
for (int i = 0; i < data.size(); i++) {
CalendarBean bean = data.get(i);
View view = getChildAt(i);
View chidView = LayoutInflater.from(getContext()).inflate(R.layout.item_calendar, null);
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(px(48), px(48));
chidView.setLayoutParams(params);
TextView textView = (TextView) chidView.findViewById(R.id.text);
RelativeLayout rv_day = (RelativeLayout) chidView.findViewById(R.id.rv_day);
ImageView iv_star = (ImageView) chidView.findViewById(R.id.iv_star);
textView.setText("" + bean.day);
if (bean.mothFlag != 0) {
textView.setTextColor(0xff9299a1);
rv_day.setVisibility(View.GONE);
} else {
if(bean.hasEvent){
iv_star.setVisibility(View.VISIBLE);
}
textView.setTextColor(Color.BLACK);
}
int[]date=CalendarUtil.getYMD(new Date());
if((bean.year > date[0]) || (bean.year == date[0] && bean.moth==date[1] && bean.day > date[2]) || (bean.year == date[0] && bean.moth>date[1]) ){
textView.setTextColor(0xff9299a1);
}
if (view == null || view != chidView) {
addViewInLayout(chidView, i+1, chidView.getLayoutParams(), true);
}
if(isToday&&selectPostion==-1){
if(bean.year==date[0]&&bean.moth==date[1]&&bean.day==date[2]){
selectPostion=i+1;
}
}else {
if (selectPostion == -1 && bean.day == 1) {
selectPostion = i+1;
}
}
chidView.setSelected(selectPostion==i+1);
setItemClick(chidView, i+1, bean);
}
}
实现左右滑动,我们这里使用CalendarDateView继承ViewPager这个类,设置最当前页是在Integer.MAX_VALUE/2来确保左右可滑,在适配器里添加一个CalendarView并设置数据
view.setData(getMonthOfDayList(dateArr[0],dateArr[1]+position-Integer.MAX_VALUE/2),position==Integer.MAX_VALUE/2);
好了,大功告成
所有的代码都在我的GitHub里面
https://github.com/mianmian520/Calendar