公司项目需要一个功能全面的日历,然后就在网上找demo,然后根据demo自己深度定制了一个日历,基本满足了需求,现在把日历核心代码共享给大家。源码下载地址http://download.csdn.net/detail/voidmain_123/9275921

CollapseCalendarView.java
只需要将该控件引入到布局文件中
package com.eroad.widget.calendar;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

import org.joda.time.LocalDate;
import org.json.JSONObject;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.eroad.widget.calendar.manager.CalendarManager;
import com.eroad.widget.calendar.manager.CalendarManager.State;
import com.eroad.widget.calendar.manager.Day;
import com.eroad.widget.calendar.manager.Month;
import com.eroad.widget.calendar.manager.ResizeManager;
import com.eroad.widget.calendar.manager.Week;
import com.eroad.widget.calendar.widget.DayView;
import com.eroad.widget.calendar.widget.WeekView;
import com.example.calendarnew.R;

/**
* 日历View
* @author MaJian
*
*/
@SuppressLint({ “SimpleDateFormat”, “NewApi” }) public class CollapseCalendarView extends LinearLayout implements View.OnClickListener {

public static final String TAG = "CalendarView";private CalendarManager mManager;private TextView mTitleView;private ImageButton mPrev;private ImageButton mNext;private LinearLayout mWeeksView;private final LayoutInflater mInflater;private final RecycleBin mRecycleBin = new RecycleBin();private OnDateSelect mListener;private TextView mSelectionText;private LinearLayout mHeader;private ResizeManager mResizeManager;private ImageView mIvPre;private ImageView mIvNext;private Animation left_in;private Animation right_in;private boolean initialized;private String[] weeks;private OnTitleClickListener titleClickListener;private JSONObject dataObject;                          //日历数据源private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");private boolean showChinaDay = true;                    //是否显示农历日期public CollapseCalendarView(Context context) {    this(context, null);    onFinishInflate();}public void showChinaDay(boolean showChinaDay){    this.showChinaDay = showChinaDay;    populateLayout();}/** * 设置标题点击监听器 * @param titleClickListener */public void setTitleClickListener(OnTitleClickListener titleClickListener){    this.titleClickListener = titleClickListener;}public CollapseCalendarView(Context context, AttributeSet attrs) {    this(context, attrs, R.attr.calendarViewStyle);}public void setArrayData(JSONObject jsonObject){    this.dataObject = jsonObject;}public interface OnTitleClickListener{    public void onTitleClick();}@SuppressLint("NewApi")public CollapseCalendarView(Context context, AttributeSet attrs, int defStyle) {    super(context, attrs, defStyle);    weeks = getResources().getStringArray(R.array.weeks);    mInflater = LayoutInflater.from(context);    mResizeManager = new ResizeManager(this);    inflate(context, R.layout.calendar_layout, this);    setOrientation(VERTICAL);    setBackgroundColor(getResources().getColor(R.color.cal_color_white));    mIvPre = new ImageView(getContext());    mIvNext = new ImageView(getContext());    RelativeLayout.LayoutParams param = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, android.widget.RelativeLayout.LayoutParams.WRAP_CONTENT);    mIvPre.setLayoutParams(param);    mIvNext.setLayoutParams(param);    initAnim();}/** * 初始化左右滑动动画 */private void initAnim(){    left_in = AnimationUtils.makeInAnimation(getContext(), true);    right_in = AnimationUtils.makeInAnimation(getContext(), false);}/** * 初始化日历管理器 * @param manager 日历管理器对象 */public void init(CalendarManager manager) {    if (manager != null) {        mManager = manager;        if (mListener != null) {            mListener.onDateSelected(mManager.getSelectedDay());        }        populateLayout();    }}/** * 切换到指定某天界面 * @param date yyyy-MM-dd */public void changeDate(String date){    if (date.compareTo(mManager.getSelectedDay().toString()) > 0) {        this.setAnimation(right_in);        right_in.start();    } else if (date.compareTo(mManager.getSelectedDay().toString()) < 0) {        this.setAnimation(left_in);        left_in.start();    }    try {        mManager.init(LocalDate.fromDateFields(sdf.parse(date)));    } catch (ParseException e) {        // TODO Auto-generated catch block        e.printStackTrace();    }    init(mManager);}public CalendarManager getManager() {    return mManager;}@Overridepublic void onClick(View v) {    if (mManager != null) {        int id = v.getId();        if (id == R.id.prev) {            prev();        } else if (id == R.id.next) {            next();        } else if (id == R.id.title) {            if (titleClickListener != null) {                titleClickListener.onTitleClick();            }        }    }}@SuppressLint("WrongCall")@Overrideprotected void dispatchDraw(  Canvas canvas) {    mResizeManager.onDraw();    super.dispatchDraw(canvas);}public CalendarManager.State getState() {    if (mManager != null) {        return mManager.getState();    } else {        return null;    }}public void setDateSelectListener(OnDateSelect listener) {    mListener = listener;}/** * 设置日历标题 * @param text */public void setTitle(String text) {    if (TextUtils.isEmpty(text)) {        mHeader.setVisibility(View.VISIBLE);        mSelectionText.setVisibility(View.GONE);    } else {        mHeader.setVisibility(View.GONE);        mSelectionText.setVisibility(View.VISIBLE);        mSelectionText.setText(text);    }}/** * 显示日历自带标题 */public void showHeader(){    mHeader.setVisibility(View.VISIBLE);}/** * 隐藏日历自带标题 */public void hideHeader(){    mHeader.setVisibility(View.GONE);}@Overridepublic boolean onInterceptTouchEvent(MotionEvent ev) {    return mResizeManager.onInterceptTouchEvent(ev);}@Overridepublic boolean onTouchEvent(  MotionEvent event) {    super.onTouchEvent(event);    return mResizeManager.onTouchEvent(event);}/** * 周-月 */public void weekToMonth(){    if (mManager.getState() == CalendarManager.State.WEEK) {        mManager.toggleView();    }}/** * 月-周 */public void monthToWeek(){    if (mManager.getState() == CalendarManager.State.MONTH) {        mManager.toggleView();    }}@Overrideprotected void onFinishInflate() {    super.onFinishInflate();    mTitleView = (TextView) findViewById(R.id.title);    mTitleView.setOnClickListener(this);    mPrev = (ImageButton) findViewById(R.id.prev);    mNext = (ImageButton) findViewById(R.id.next);    mWeeksView = (LinearLayout) findViewById(R.id.weeks);    mHeader = (LinearLayout) findViewById(R.id.header);    mSelectionText = (TextView) findViewById(R.id.selection_title);    mPrev.setOnClickListener(this);    mNext.setOnClickListener(this);    populateLayout();}/** * 绘制日历周标题 */private void populateDays() {    if (!initialized) {        CalendarManager manager = getManager();        if (manager != null) {            LinearLayout layout = (LinearLayout) findViewById(R.id.days);            for (int i = 0; i < 7; i++) {                TextView textView = (TextView) layout.getChildAt(i);                textView.setText(weeks[i]);                if (i > 4) {                    textView.setTextColor(getResources().getColor(R.color.cal_blue_dark));                }            }            initialized = true;        }    }}/** * 刷新日历View */public synchronized void populateLayout() {    if (mManager != null) {        populateDays();        if (mPrev != null) {            mPrev.setEnabled(mManager.hasPrev());            mNext.setEnabled(mManager.hasNext());            mTitleView.setText(mManager.getHeaderText());            if (mManager.getState() == CalendarManager.State.MONTH) {                populateMonthLayout((Month) mManager.getUnits());            } else {                populateWeekLayout((Week) mManager.getUnits());            }        }    }}/** * 刷新日历Month View * @param month 月份 */private void populateMonthLayout(Month month) {    List weeks = month.getWeeks();    int cnt = weeks.size();    for (int i = 0; i < cnt; i++) {        WeekView weekView = getWeekView(i);        populateWeekLayout(weeks.get(i), weekView);    }    int childCnt = mWeeksView.getChildCount();    if (cnt < childCnt) {        for (int i = cnt; i < childCnt; i++) {            cacheView(i);        }    }}/** * 刷新日历Week View * @param week 周 */private void populateWeekLayout(Week week) {    WeekView weekView = getWeekView(0);    populateWeekLayout(week, weekView);    int cnt = mWeeksView.getChildCount();    if (cnt > 1) {        for (int i = cnt - 1; i > 0; i--) {            cacheView(i);        }    }}private void populateWeekLayout(  Week week,   WeekView weekView) {    List days = week.getDays();    for (int i = 0; i < 7; i++) {        final Day day = days.get(i);        LinearLayout layout = (LinearLayout) weekView.getChildAt(i);        DayView dayView = (DayView) layout.findViewById(R.id.tvDayView);        DayView chinaDay = (DayView) layout.findViewById(R.id.tvChina);        if (showChinaDay) {            chinaDay.setVisibility(View.VISIBLE);        } else {            chinaDay.setVisibility(View.GONE);        }        View viewPoint = layout.findViewById(R.id.view_point);        TextView tvDayType = (TextView) layout.findViewById(R.id.tv_day_type);        //渲染日期上班休假类型        if (dataObject != null && dataObject.optJSONObject(sdf.format(day.getDate().toDate())) != null) {            JSONObject jsonObject = dataObject.optJSONObject(sdf.format(day.getDate().toDate()));            if (!TextUtils.isEmpty(jsonObject.optString("type"))) {                tvDayType.setText(jsonObject.optString("type"));                tvDayType.setVisibility(View.VISIBLE);                if (jsonObject.optString("type").equals("假")) {                    tvDayType.setBackground(getResources().getDrawable(R.drawable.bg_day_type_red));                } else if (jsonObject.optString("type").equals("班")) {                    tvDayType.setBackground(getResources().getDrawable(R.drawable.bg_day_type_blue));                }            } else {                tvDayType.setVisibility(View.GONE);            }            if (jsonObject.optJSONArray("list") != null && jsonObject.optJSONArray("list").length() >= 0) {                viewPoint.setVisibility(View.VISIBLE);            } else {                viewPoint.setVisibility(View.INVISIBLE);            }        } else {            tvDayType.setVisibility(View.INVISIBLE);            viewPoint.setVisibility(View.INVISIBLE);        }        dayView.setText(day.getText());        chinaDay.setText(day.getChinaDate());        if (day.getDate().getYear() == mManager.getCurrentMonthDate().getYear()                 && day.getDate().getMonthOfYear() == mManager.getCurrentMonthDate().getMonthOfYear()                || mManager.getState() == State.WEEK) {            //如果日期是当前月份            if (i > 4) {                //周末                dayView.setTextColor(getResources().getColor(R.color.cal_blue_dark));                chinaDay.setTextColor(getResources().getColor(R.color.cal_blue_dark));            } else {                //非周末                dayView.setTextColor(getResources().getColor(R.color.cal_text_normal));                chinaDay.setTextColor(getResources().getColor(R.color.cal_text_normal));            }        } else {            //日期不是当前月份            if (i > 4) {                //周末                dayView.setTextColor(getResources().getColor(R.color.cal_blue_light));                chinaDay.setTextColor(getResources().getColor(R.color.cal_blue_light));            } else {                //非周末                dayView.setTextColor(getResources().getColor(R.color.cal_line_grey));                chinaDay.setTextColor(getResources().getColor(R.color.cal_line_grey));            }        }        layout.setSelected(day.isSelected());        if (day.getDate().equals(mManager.getToday()) && day.isSelected()) {            //日期对象是今天,并且被选中            if (day.getDate().getYear() == mManager.getCurrentMonthDate().getYear()                     && day.getDate().getMonthOfYear() == mManager.getCurrentMonthDate().getMonthOfYear()) {                //如果日期是当前月份                if (i > 4) {                    //周末                    dayView.setTextColor(getResources().getColorStateList(R.color.text_calendar_week));                    chinaDay.setTextColor(getResources().getColorStateList(R.color.text_calendar_week));                } else {                    //非周末                    dayView.setTextColor(getResources().getColorStateList(R.color.text_calendar));                    chinaDay.setTextColor(getResources().getColorStateList(R.color.text_calendar));                }            } else {                //日期不是当前月份                if (i > 4) {                    //周末                    dayView.setTextColor(getResources().getColorStateList(R.color.text_calendar_week_out_month));                    chinaDay.setTextColor(getResources().getColorStateList(R.color.text_calendar_week_out_month));                } else {                    //非周末                    dayView.setTextColor(getResources().getColorStateList(R.color.text_calendar_out_month));                    chinaDay.setTextColor(getResources().getColorStateList(R.color.text_calendar_out_month));                }            }            layout.setBackground(getResources().getDrawable(R.drawable.bg_btn_calendar_today_selected));            viewPoint.setBackground(getResources().getDrawable(R.drawable.bg_calendar_point_white));            layout.setSelected(true);        } else if (day.getDate().equals(mManager.getToday())) {            //日期对象今天            viewPoint.setBackground(getResources().getDrawable(R.drawable.bg_calendar_point_blue));            layout.setBackground(getResources().getDrawable(R.drawable.bg_btn_calendar_today));            layout.setSelected(true);        } else {            //日期对象被选中            viewPoint.setBackground(getResources().getDrawable(R.drawable.bg_calendar_point_blue));            layout.setBackground(getResources().getDrawable(R.drawable.bg_btn_calendar));        }        dayView.setCurrent(day.isCurrent());        boolean enables = day.isEnabled();        dayView.setEnabled(enables);        if (enables) { // 解除点击限制,所有的都可以点击            layout.setOnClickListener(new OnClickListener() {                @Override                public void onClick(View v) {                    LocalDate date = day.getDate();                    if (mManager.getState() == State.MONTH) {                        //判断当前视图状态为月份视图                        if (date.getYear() > mManager.getCurrentMonthDate().getYear()) {                            //选中日期年份大于当前显示年份                            next();                        } else if (date.getYear() < mManager.getCurrentMonthDate().getYear()) {                            //选中日期年份小于当前显示年份                            prev();                        } else {                            //选中日期年份等于当前显示年份                            if (date.getMonthOfYear() > mManager.getCurrentMonthDate().getMonthOfYear()) {                                //选中月份大于当前月份                                next();                            } else if (date.getMonthOfYear() < mManager.getCurrentMonthDate().getMonthOfYear()) {                                //选中月份小于当前月份                                prev();                            }                        }                    }                    if (mManager.selectDay(date)) {                        populateLayout();                        if (mListener != null) {                            //执行选中回调                            mListener.onDateSelected(date);                        }                    }                }            });        } else {            dayView.setOnClickListener(null);        }    }}/** * 翻转到前一页 */public void prev(){    if (mManager.prev()) {        populateLayout();    }    if (mListener != null) {        //执行选中回调        mListener.onDateSelected(mManager.getSelectedDay());    }    this.setAnimation(left_in);    left_in.start();}/** * 翻转到下一页 */public void next(){    if (mManager.next()) {        populateLayout();    }    if (mListener != null) {        //执行选中回调        mListener.onDateSelected(mManager.getSelectedDay());    }    this.setAnimation(right_in);    right_in.start();}public LinearLayout getWeeksView() {    return mWeeksView;}private WeekView getWeekView(int index) {    int cnt = mWeeksView.getChildCount();    if(cnt < index + 1) {        for (int i = cnt; i < index + 1; i++) {            View view = getView();            mWeeksView.addView(view);        }    }    return (WeekView) mWeeksView.getChildAt(index);}private View getView() {    View view = mRecycleBin.recycleView();    if (view == null) {        view = mInflater.inflate(R.layout.week_layout, this, false);    } else {        view.setVisibility(View.VISIBLE);    }    return view;}private void cacheView(int index) {    View view = mWeeksView.getChildAt(index);    if(view != null) {        mWeeksView.removeViewAt(index);        mRecycleBin.addView(view);    }}public LocalDate getSelectedDate() {    return mManager.getSelectedDay();}@Overrideprotected void onDetachedFromWindow() {    super.onDetachedFromWindow();    mResizeManager.recycle();}private class RecycleBin {    private final Queue mViews = new LinkedList();    public View recycleView() {        return mViews.poll();    }    public void addView(View view) {        mViews.add(view);    }}public interface OnDateSelect {    public void onDateSelected(LocalDate date);}

}

MainActivity主界面
基本的事件处理以及监听器的使用
package com.eroad.widget.calendar;

import java.text.SimpleDateFormat;
import java.util.Calendar;

import org.joda.time.LocalDate;
import org.json.JSONArray;
import org.json.JSONObject;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Toast;

import com.eroad.widget.calendar.CollapseCalendarView.OnDateSelect;
import com.eroad.widget.calendar.CollapseCalendarView.OnTitleClickListener;
import com.eroad.widget.calendar.manager.CalendarManager;
import com.eroad.widget.calendar.manager.CalendarManager.OnMonthChangeListener;
import com.example.calendarnew.R;
/**
* Main
* @author MaJian
*
*/
public class MainActivity extends Activity {

private CollapseCalendarView calendarView;private CalendarManager mManager;private JSONObject json;private SimpleDateFormat sdf;private boolean show = false;@Overrideprotected void onCreate(Bundle savedInstanceState) {    // TODO Auto-generated method stub    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    sdf = new SimpleDateFormat("yyyy-MM-dd");    calendarView = (CollapseCalendarView) findViewById(R.id.calendar);    mManager = new CalendarManager(LocalDate.now(),            CalendarManager.State.MONTH, LocalDate.now().withYear(100),            LocalDate.now().plusYears(100));    //月份切换监听器    mManager.setMonthChangeListener(new OnMonthChangeListener() {        @Override        public void monthChange(String month, LocalDate mSelected) {            // TODO Auto-generated method stub            Toast.makeText(MainActivity.this, month, Toast.LENGTH_SHORT).show();        }    });    /**     * 日期选中监听器     */    calendarView.setDateSelectListener(new OnDateSelect() {        @Override        public void onDateSelected(LocalDate date) {            // TODO Auto-generated method stub            Toast.makeText(MainActivity.this, date.toString(), Toast.LENGTH_SHORT).show();        }    });    calendarView.setTitleClickListener(new OnTitleClickListener() {        @Override        public void onTitleClick() {            // TODO Auto-generated method stub            Toast.makeText(MainActivity.this, "点击标题", Toast.LENGTH_SHORT).show();        }    });    //回到今天    findViewById(R.id.btn_today).setOnClickListener(new OnClickListener() {        @Override        public void onClick(View v) {            // TODO Auto-generated method stub            calendarView.changeDate(LocalDate.now().toString());        }    });    //周月切换    findViewById(R.id.btn_changemode).setOnClickListener(new OnClickListener() {        @Override        public void onClick(View v) {            // TODO Auto-generated method stub            mManager.toggleView();            calendarView.populateLayout();        }    });    //显示或者隐藏农历    findViewById(R.id.btn_hide).setOnClickListener(new OnClickListener() {        @Override        public void onClick(View v) {            // TODO Auto-generated method stub            calendarView.showChinaDay(show);            show = !show;        }    });    Calendar cal = Calendar.getInstance();    cal.set(Calendar.MONTH, 9);    cal.set(Calendar.DAY_OF_MONTH, 0);    json = new JSONObject();    try {        for (int i = 0; i < 30; i++) {            JSONObject jsonObject2 = new JSONObject();            if (i <= 6) {                jsonObject2.put("type", "休");            } else if ( i > 6 && i< 11) {                jsonObject2.put("type", "班");            }            if (i%3 == 0) {                jsonObject2.put("list", new JSONArray());            }            json.put(sdf.format(cal.getTime()), jsonObject2);            cal.add(Calendar.DAY_OF_MONTH, 1);        }    } catch (Exception e) {        // TODO: handle exception        e.printStackTrace();    }    //设置数据显示    calendarView.setArrayData(json);    //初始化日历管理器    calendarView.init(mManager);}

}

布局文件源码

<?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" >    <com.eroad.widget.calendar.CollapseCalendarView        android:id="@+id/calendar"        android:layout_width="match_parent"        android:layout_height="wrap_content" >    com.eroad.widget.calendar.CollapseCalendarView>    <Button        android:id="@+id/btn_today"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="回到今天" />    <Button        android:id="@+id/btn_changemode"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="周月切换" />    <Button        android:id="@+id/btn_hide"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="隐藏、显示农历" />LinearLayout>

下面给大家分享下效果图





如果大家比较满意可以下载完整版demo
链接:http://download.csdn.net/detail/voidmain_123/9275921

更多相关文章

  1. android studio删除module
  2. Android(安卓)"java.lang.NoClassDefFoundError:*"报错的处理方
  3. android 点击EditText 弹出日期选择器DatePickerDialog
  4. andrioid——checkbox勾选按钮自定义样式
  5. Android——使用DatePicker和TimePicker显示当前日期和时间
  6. Android根据当前时间获取前面的时间日期,或者之后的时间日期
  7. Android(安卓)RadioGroup和RadioButton案例及详解
  8. 最简便实现Android(安卓)ListView选中item高亮显示
  9. Android(安卓)studio 常用快捷键记录

随机推荐

  1. Android TabHost与FragmentActivity
  2. Android:JNI Local Reference Changes in
  3. android 文件搜索
  4. Android4.0中修改挂断键(ENDCALL)的默认行
  5. Android/Java仿微信按时间长短分类显示时
  6. Android带参数链接请求服务器
  7. android 源码的一些修改定制方案
  8. 禁止状态栏下拉
  9. Android intent 传递数组对象序列化
  10. Android监听Dialog点击外部区域