赞
踩
使用Activity 制作一个日历控件
1、日历View
- import java.util.Calendar;
- import java.util.Date;
-
- import android.content.Context;
- import android.graphics.Canvas;
- import android.graphics.Color;
- import android.graphics.Paint;
- import android.graphics.Path;
- import android.graphics.Typeface;
- import android.util.AttributeSet;
- import android.util.Log;
- import android.view.MotionEvent;
- import android.view.View;
-
- public class CalendarView extends View implements View.OnTouchListener {
- private final static String TAG = "anCalendar";
- private Date selectedStartDate;
- private Date selectedEndDate;
- private Date curDate; // 当前日历显示的月
- private Date today; // 今天的日期文字显示红色
- private Date downDate; // 手指按下状态时临时日期
- private Date showFirstDate, showLastDate; // 日历显示的第一个日期和最后一个日期
- private int downIndex; // 按下的格子索引
- private Calendar calendar;
- private Surface surface;
- private int[] date = new int[42]; // 日历显示数字
- private int curStartIndex, curEndIndex; // 当前显示的日历起始的索引
- // private boolean completed = false; // 为false表示只选择了开始日期,true表示结束日期也选择了
- // 给控件设置监听事件
- private OnItemClickListener onItemClickListener;
-
- public CalendarView(Context context) {
- super(context);
- init();
-
- }
-
- public CalendarView(Context context, AttributeSet attrs) {
- super(context, attrs);
- init();
- }
-
- private void init() {
-
- curDate = selectedStartDate = selectedEndDate = today = new Date();
- calendar = Calendar.getInstance();
- calendar.setTime(curDate);
- surface = new Surface();
- surface.density = getResources().getDisplayMetrics().density;
- setBackgroundColor(surface.bgColor);
- setOnTouchListener(this);
- }
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- surface.width = getResources().getDisplayMetrics().widthPixels * 4 / 5;
- surface.height = (int) (getResources().getDisplayMetrics().heightPixels * 2 / 5);
- // if (View.MeasureSpec.getMode(widthMeasureSpec) ==
- // View.MeasureSpec.EXACTLY) {
- // surface.width = View.MeasureSpec.getSize(widthMeasureSpec);
- // }
- // if (View.MeasureSpec.getMode(heightMeasureSpec) ==
- // View.MeasureSpec.EXACTLY) {
- // surface.height = View.MeasureSpec.getSize(heightMeasureSpec);
- // }
- widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(surface.width, View.MeasureSpec.EXACTLY);
- heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(surface.height, View.MeasureSpec.EXACTLY);
- setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- }
-
- @Override
- protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- Log.d(TAG, "[onLayout] changed:" + (changed ? "new size" : "not change") + " left:" + left + " top:" + top + " right:" + right + " bottom:" + bottom);
- if (changed) {
- surface.init();
- }
- super.onLayout(changed, left, top, right, bottom);
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- Log.d(TAG, "onDraw");
- // 画框
- canvas.drawPath(surface.boxPath, surface.borderPaint);
- // 年月
- // String monthText = getYearAndmonth();
- // float textWidth = surface.monthPaint.measureText(monthText);
- // canvas.drawText(monthText, (surface.width - textWidth) / 2f,
- // surface.monthHeight * 3 / 4f, surface.monthPaint);
- // 上一月/下一月
- // canvas.drawPath(surface.preMonthBtnPath,
- // surface.monthChangeBtnPaint);
- // canvas.drawPath(surface.nextMonthBtnPath,
- // surface.monthChangeBtnPaint);
- // 星期
- float weekTextY = surface.monthHeight + surface.weekHeight * 3 / 4f;
- // 星期背景
- // surface.cellBgPaint.setColor(surface.textColor);
- // canvas.drawRect(surface.weekHeight, surface.width,
- // surface.weekHeight, surface.width, surface.cellBgPaint);
- for (int i = 0; i < surface.weekText.length; i++) {
- float weekTextX = i * surface.cellWidth + (surface.cellWidth - surface.weekPaint.measureText(surface.weekText[i])) / 2f;
- canvas.drawText(surface.weekText[i], weekTextX, weekTextY, surface.weekPaint);
- }
-
- // 计算日期
- calculateDate();
- // 按下状态,选择状态背景色
- drawDownOrSelectedBg(canvas);
- // write date number
- // today index
- int todayIndex = -1;
- calendar.setTime(curDate);
- String curYearAndMonth = calendar.get(Calendar.YEAR) + "" + calendar.get(Calendar.MONTH);
- calendar.setTime(today);
- String todayYearAndMonth = calendar.get(Calendar.YEAR) + "" + calendar.get(Calendar.MONTH);
- if (curYearAndMonth.equals(todayYearAndMonth)) {
- int todayNumber = calendar.get(Calendar.DAY_OF_MONTH);
- todayIndex = curStartIndex + todayNumber - 1;
- }
- for (int i = 0; i < 42; i++) {
- int color = surface.textColor;
- if (isLastMonth(i)) {
- color = surface.borderColor;
- } else if (isNextMonth(i)) {
- color = surface.borderColor;
- }
- if (todayIndex != -1 && i == todayIndex) {
- color = surface.todayNumberColor;
- }
- drawCellText(canvas, i, date[i] + "", color);
- }
- super.onDraw(canvas);
- }
-
- private void calculateDate() {
- calendar.setTime(curDate);
- calendar.set(Calendar.DAY_OF_MONTH, 1);
- int dayInWeek = calendar.get(Calendar.DAY_OF_WEEK);
- Log.d(TAG, "day in week:" + dayInWeek);
- int monthStart = dayInWeek;
- if (monthStart == 1) {
- monthStart = 8;
- }
- monthStart -= 1; // 以日为开头-1,以星期一为开头-2
- curStartIndex = monthStart;
- date[monthStart] = 1;
- // last month
- if (monthStart > 0) {
- calendar.set(Calendar.DAY_OF_MONTH, 0);
- int dayInmonth = calendar.get(Calendar.DAY_OF_MONTH);
- for (int i = monthStart - 1; i >= 0; i--) {
- date[i] = dayInmonth;
- dayInmonth--;
- }
- calendar.set(Calendar.DAY_OF_MONTH, date[0]);
- }
- showFirstDate = calendar.getTime();
- // this month
- calendar.setTime(curDate);
- calendar.add(Calendar.MONTH, 1);
- calendar.set(Calendar.DAY_OF_MONTH, 0);
- // Log.d(TAG, "m:" + calendar.get(Calendar.MONTH) + " d:" +
- // calendar.get(Calendar.DAY_OF_MONTH));
- int monthDay = calendar.get(Calendar.DAY_OF_MONTH);
- for (int i = 1; i < monthDay; i++) {
- date[monthStart + i] = i + 1;
- }
- curEndIndex = monthStart + monthDay;
- // next month
- for (int i = monthStart + monthDay; i < 42; i++) {
- date[i] = i - (monthStart + monthDay) + 1;
- }
- if (curEndIndex < 42) {
- // 显示了下一月的
- calendar.add(Calendar.DAY_OF_MONTH, 1);
- }
- calendar.set(Calendar.DAY_OF_MONTH, date[41]);
- showLastDate = calendar.getTime();
- }
-
- /**
- *
- * @param canvas
- * @param index
- * @param text
- */
- private void drawCellText(Canvas canvas, int index, String text, int color) {
- int x = getXByIndex(index);
- int y = getYByIndex(index);
- surface.datePaint.setColor(color);
- float cellY = surface.monthHeight + surface.weekHeight + (y - 1) * surface.cellHeight + surface.cellHeight * 3 / 4f;
- float cellX = (surface.cellWidth * (x - 1)) + (surface.cellWidth - surface.datePaint.measureText(text)) / 2f;
- canvas.drawText(text, cellX, cellY, surface.datePaint);
- }
-
- /**
- *
- * @param canvas
- * @param index
- * @param color
- */
- private void drawCellBg(Canvas canvas, int index, int color) {
- int x = getXByIndex(index);
- int y = getYByIndex(index);
- surface.cellBgPaint.setColor(color);
- float left = surface.cellWidth * (x - 1) + surface.borderWidth;
- float top = surface.monthHeight + surface.weekHeight + (y - 1) * surface.cellHeight + surface.borderWidth;
- canvas.drawRect(left, top, left + surface.cellWidth - surface.borderWidth, top + surface.cellHeight - surface.borderWidth, surface.cellBgPaint);
- }
-
- private void drawDownOrSelectedBg(Canvas canvas) {
- // down and not up
- if (downDate != null) {
- drawCellBg(canvas, downIndex, surface.cellDownColor);
- }
- // selected bg color
- if (!selectedEndDate.before(showFirstDate) && !selectedStartDate.after(showLastDate)) {
- int[] section = new int[] { -1, -1 };
- calendar.setTime(curDate);
- calendar.add(Calendar.MONTH, -1);
- findSelectedIndex(0, curStartIndex, calendar, section);
- if (section[1] == -1) {
- calendar.setTime(curDate);
- findSelectedIndex(curStartIndex, curEndIndex, calendar, section);
- }
- if (section[1] == -1) {
- calendar.setTime(curDate);
- calendar.add(Calendar.MONTH, 1);
- findSelectedIndex(curEndIndex, 42, calendar, section);
- }
- if (section[0] == -1) {
- section[0] = 0;
- }
- if (section[1] == -1) {
- section[1] = 41;
- }
- for (int i = section[0]; i <= section[1]; i++) {
- drawCellBg(canvas, i, surface.cellSelectedColor);
- }
- }
- }
-
- private void findSelectedIndex(int startIndex, int endIndex, Calendar calendar, int[] section) {
- for (int i = startIndex; i < endIndex; i++) {
- calendar.set(Calendar.DAY_OF_MONTH, date[i]);
- Date temp = calendar.getTime();
- // Log.d(TAG, "temp:" + temp.toLocaleString());
- if (temp.compareTo(selectedStartDate) == 0) {
- section[0] = i;
- }
- if (temp.compareTo(selectedEndDate) == 0) {
- section[1] = i;
- return;
- }
- }
- }
-
- public Date getSelectedStartDate() {
- return selectedStartDate;
- }
-
- public Date getSelectedEndDate() {
- return selectedEndDate;
- }
-
- private boolean isLastMonth(int i) {
- if (i < curStartIndex) {
- return true;
- }
- return false;
- }
-
- private boolean isNextMonth(int i) {
- if (i >= curEndIndex) {
- return true;
- }
- return false;
- }
-
- private int getXByIndex(int i) {
- return i % 7 + 1; // 1 2 3 4 5 6 7
- }
-
- private int getYByIndex(int i) {
- return i / 7 + 1; // 1 2 3 4 5 6
- }
-
- // 获得当前应该显示的年月
- public String getYearAndmonth() {
- calendar.setTime(curDate);
- int year = calendar.get(Calendar.YEAR);
- int month = calendar.get(Calendar.MONTH);
- return year + "-" + surface.monthText[month];
- }
-
- // 上一月
- public String clickLeftMonth() {
- calendar.setTime(curDate);
- calendar.add(Calendar.MONTH, -1);
- curDate = calendar.getTime();
- invalidate();
- return getYearAndmonth();
- }
-
- // 下一月
- public String clickRightMonth() {
- calendar.setTime(curDate);
- calendar.add(Calendar.MONTH, 1);
- curDate = calendar.getTime();
- invalidate();
- return getYearAndmonth();
- }
-
- private void setSelectedDateByCoor(float x, float y) {
- // change month
- // if (y < surface.monthHeight) {
- // // pre month
- // if (x < surface.monthChangeWidth) {
- // calendar.setTime(curDate);
- // calendar.add(Calendar.MONTH, -1);
- // curDate = calendar.getTime();
- // }
- // // next month
- // else if (x > surface.width - surface.monthChangeWidth) {
- // calendar.setTime(curDate);
- // calendar.add(Calendar.MONTH, 1);
- // curDate = calendar.getTime();
- // }
- // }
- // cell click down
- if (y > surface.monthHeight + surface.weekHeight) {
- int m = (int) (Math.floor(x / surface.cellWidth) + 1);
- int n = (int) (Math.floor((y - (surface.monthHeight + surface.weekHeight)) / Float.valueOf(surface.cellHeight)) + 1);
- downIndex = (n - 1) * 7 + m - 1;
- Log.d(TAG, "downIndex:" + downIndex);
- calendar.setTime(curDate);
- if (isLastMonth(downIndex)) {
- calendar.add(Calendar.MONTH, -1);
- } else if (isNextMonth(downIndex)) {
- calendar.add(Calendar.MONTH, 1);
- }
- calendar.set(Calendar.DAY_OF_MONTH, date[downIndex]);
- downDate = calendar.getTime();
- }
- invalidate();
- }
-
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- setSelectedDateByCoor(event.getX(), event.getY());
- break;
- case MotionEvent.ACTION_UP:
- if (downDate != null) {
- // if (!completed) {
- // if (downDate.before(selectedStartDate)) {
- // selectedEndDate = selectedStartDate;
- // selectedStartDate = downDate;
- // } else {
- // selectedEndDate = downDate;
- // }
- // completed = true;
- // } else {
- // selectedStartDate = selectedEndDate = downDate;
- // completed = false;
- // }
- selectedStartDate = selectedEndDate = downDate;
- // 响应监听事件
- onItemClickListener.OnItemClick(selectedStartDate);
- // Log.d(TAG, "downdate:" + downDate.toLocaleString());
- // Log.d(TAG, "start:" + selectedStartDate.toLocaleString());
- // Log.d(TAG, "end:" + selectedEndDate.toLocaleString());
- downDate = null;
- invalidate();
- }
- break;
- }
- return true;
- }
-
- // 给控件设置监听事件
- public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
- this.onItemClickListener = onItemClickListener;
- }
-
- // 监听接口
- public interface OnItemClickListener {
- void OnItemClick(Date date);
- }
-
- /**
- *
- * 1. 布局尺寸 2. 文字颜色,大小 3. 当前日期的颜色,选择的日期颜色
- */
- private class Surface {
- public float density;
- public int width; // 整个控件的宽度
- public int height; // 整个控件的高度
- public float monthHeight; // 显示月的高度
- // public float monthChangeWidth; // 上一月、下一月按钮宽度
- public float weekHeight; // 显示星期的高度
- public float cellWidth; // 日期方框宽度
- public float cellHeight; // 日期方框高度
- public float borderWidth;
- public int bgColor = Color.parseColor("#FFFFFF");
- private int textColor = Color.BLACK;
- // private int textColorUnimportant = Color.parseColor("#666666");
- private int btnColor = Color.parseColor("#666666");
- private int borderColor = Color.parseColor("#CCCCCC");
- public int todayNumberColor = Color.RED;
- public int cellDownColor = Color.parseColor("#CCFFFF");
- public int cellSelectedColor = Color.parseColor("#99CCFF");
- public Paint borderPaint;
- public Paint monthPaint;
- public Paint weekPaint;
- public Paint datePaint;
- public Paint monthChangeBtnPaint;
- public Paint cellBgPaint;
- public Path boxPath; // 边框路径
- // public Path preMonthBtnPath; // 上一月按钮三角形
- // public Path nextMonthBtnPath; // 下一月按钮三角形
- public String[] weekText = { "日", "一", "二", "三", "四", "五", "六" };
- public String[] monthText = { "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月" };
-
- public void init() {
- float temp = height / 7f;
- monthHeight = 0;// (float) ((temp + temp * 0.3f) * 0.6);
- // monthChangeWidth = monthHeight * 1.5f;
- weekHeight = (float) ((temp + temp * 0.3f) * 0.7);
- cellHeight = (height - monthHeight - weekHeight) / 6f;
- cellWidth = width / 7f;
- borderPaint = new Paint();
- borderPaint.setColor(borderColor);
- borderPaint.setStyle(Paint.Style.STROKE);
- borderWidth = (float) (0.5 * density);
- // Log.d(TAG, "borderwidth:" + borderWidth);
- borderWidth = borderWidth < 1 ? 1 : borderWidth;
- borderPaint.setStrokeWidth(borderWidth);
- monthPaint = new Paint();
- monthPaint.setColor(textColor);
- monthPaint.setAntiAlias(true);
- float textSize = cellHeight * 0.4f;
- Log.d(TAG, "text size:" + textSize);
- monthPaint.setTextSize(textSize);
- monthPaint.setTypeface(Typeface.DEFAULT_BOLD);
- weekPaint = new Paint();
- weekPaint.setColor(textColor);
- weekPaint.setAntiAlias(true);
- float weekTextSize = weekHeight * 0.6f;
- weekPaint.setTextSize(weekTextSize);
- weekPaint.setTypeface(Typeface.DEFAULT_BOLD);
- datePaint = new Paint();
- datePaint.setColor(textColor);
- datePaint.setAntiAlias(true);
- float cellTextSize = cellHeight * 0.5f;
- datePaint.setTextSize(cellTextSize);
- datePaint.setTypeface(Typeface.DEFAULT_BOLD);
- boxPath = new Path();
- // boxPath.addRect(0, 0, width, height, Direction.CW);
- // boxPath.moveTo(0, monthHeight);
- boxPath.rLineTo(width, 0);
- boxPath.moveTo(0, monthHeight + weekHeight);
- boxPath.rLineTo(width, 0);
- for (int i = 1; i < 6; i++) {
- boxPath.moveTo(0, monthHeight + weekHeight + i * cellHeight);
- boxPath.rLineTo(width, 0);
- boxPath.moveTo(i * cellWidth, monthHeight);
- boxPath.rLineTo(0, height - monthHeight);
- }
- boxPath.moveTo(6 * cellWidth, monthHeight);
- boxPath.rLineTo(0, height - monthHeight);
- // preMonthBtnPath = new Path();
- // int btnHeight = (int) (monthHeight * 0.6f);
- // preMonthBtnPath.moveTo(monthChangeWidth / 2f, monthHeight / 2f);
- // preMonthBtnPath.rLineTo(btnHeight / 2f, -btnHeight / 2f);
- // preMonthBtnPath.rLineTo(0, btnHeight);
- // preMonthBtnPath.close();
- // nextMonthBtnPath = new Path();
- // nextMonthBtnPath.moveTo(width - monthChangeWidth / 2f,
- // monthHeight / 2f);
- // nextMonthBtnPath.rLineTo(-btnHeight / 2f, -btnHeight / 2f);
- // nextMonthBtnPath.rLineTo(0, btnHeight);
- // nextMonthBtnPath.close();
- monthChangeBtnPaint = new Paint();
- monthChangeBtnPaint.setAntiAlias(true);
- monthChangeBtnPaint.setStyle(Paint.Style.FILL_AND_STROKE);
- monthChangeBtnPaint.setColor(btnColor);
- cellBgPaint = new Paint();
- cellBgPaint.setAntiAlias(true);
- cellBgPaint.setStyle(Paint.Style.FILL);
- cellBgPaint.setColor(cellSelectedColor);
- }
- }
-
- }
- package com.nh.activity;
-
- import java.util.Date;
-
- import android.app.Activity;
- import android.content.Intent;
- import android.os.Bundle;
- import android.text.format.DateFormat;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.view.Window;
- import android.widget.TextView;
-
- import com.hugegis.whwypt.pda.R;
- import com.nh.view.CalendarView;
- import com.nh.view.CalendarView.OnItemClickListener;
-
- public class DateDialogActivity extends Activity implements OnClickListener {
-
- private CalendarView calendar;
- private TextView calendarLeft;
- private TextView calendarRight;
- private TextView calendarCenter;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- requestWindowFeature(Window.FEATURE_NO_TITLE);
- setContentView(R.layout.activity_date_dialog);
- intiview();
- }
-
- // 初始化控件
- private void intiview() {
- // 获取日历控件对象
- calendar = (CalendarView) findViewById(R.id.calendar);
- // 设置控件监听,可以监听到点击的每一天(大家也可以在控件中自行设定)
- calendar.setOnItemClickListener(new calendarItemClickListener());
- // 切换月份
- calendarLeft = (TextView) findViewById(R.id.calendarLeft);
- calendarLeft.setOnClickListener(this);
- calendarRight = (TextView) findViewById(R.id.calendarRight);
- calendarRight.setOnClickListener(this);
- // 显示月份
- calendarCenter = (TextView) findViewById(R.id.calendarCenter);
- // 获取日历中年月 ya[0]为年,ya[1]为月(格式大家可以自行在日历控件中改)
- String[] ya = calendar.getYearAndmonth().split("-");
- calendarCenter.setText(ya[1]);
-
- Intent intent = new Intent();
- setResult(1003, intent);
- }
-
- class calendarItemClickListener implements OnItemClickListener {
- @Override
- public void OnItemClick(Date date) {
- String[] startdate = gmt_utc(date).split("T");
- Intent intent = new Intent();
- intent.putExtra("date", startdate[0]);
- intent.putExtra("return", true);
- setResult(1003, intent);
- finish();
- }
- }
-
- // 时间转换
- String gmt_utc(Date date) {
- return (String) DateFormat.format("yyyy'-'MM'-'dd'T'kk':'mm':'ss'Z'", date);
- }
-
- @Override
- public void onClick(View v) {
- switch (v.getId()) {
- case R.id.calendarLeft:
- // 点击上一月 同样返回年月
- String leftYearAndmonth = calendar.clickLeftMonth();
- String[] lya = leftYearAndmonth.split("-");
- calendarCenter.setText(lya[1]);
- break;
- case R.id.calendarRight:
- // 点击下一月
- String rightYearAndmonth = calendar.clickRightMonth();
- String[] rya = rightYearAndmonth.split("-");
- calendarCenter.setText(rya[1]);
- break;
- default:
- break;
- }
- }
- }
3、布局文件
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- style="@style/AlertDialogCustom"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- tools:context="${relativePackage}.${activityClass}" >
-
- <RelativeLayout
- android:id="@+id/layout_calendar"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentLeft="true"
- android:layout_alignParentTop="true"
- android:background="@drawable/bg_date_style"
- android:visibility="visible" >
-
- <TextView
- android:id="@+id/calendarLeft"
- android:layout_width="60dp"
- android:layout_height="60dp"
- android:layout_alignParentLeft="true"
- android:background="@null"
- android:contentDescription="@null"
- android:gravity="center"
- android:text="<"
- android:textColor="@android:color/white"
- android:textSize="40sp" />
-
- <com.nh.view.CalendarView
- android:id="@+id/calendar"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_below="@+id/calendarLeft"
- android:layout_centerHorizontal="true" />
-
- <TextView
- android:id="@+id/calendarRight"
- android:layout_width="60dp"
- android:layout_height="60dp"
- android:layout_alignParentTop="true"
- android:layout_alignRight="@+id/calendar"
- android:background="@null"
- android:contentDescription="@null"
- android:gravity="center"
- android:text=">"
- android:textColor="@android:color/white"
- android:textSize="40sp" />
-
- <TextView
- android:id="@+id/calendarCenter"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignBaseline="@+id/calendarLeft"
- android:layout_alignBottom="@+id/calendarLeft"
- android:layout_centerHorizontal="true"
- android:text="@string/app_name"
- android:textColor="@android:color/black"
- android:textSize="30sp"
- android:textStyle="bold" />
- </RelativeLayout>
-
- </RelativeLayout>
3、接收日历返回值
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- // 日历
- if (resultCode == 1003) {
- if (false == data.getBooleanExtra("return", false)) {
- return;
- }
- switch (requestCode) {
- case 1001:
- // 开始时间
- String startdateString = data.getStringExtra("date");
- if (judgeDate(startdateString, requestCode)) {
- tv_start_date.setText(startdateString);
- } else {
- tv_start_date.setText(null);
- }
- break;
- case 1002:
- // 结束时间
- String enddateString = data.getStringExtra("date");
- if (judgeDate(enddateString, requestCode)) {
- tv_end_date.setText(enddateString);
- } else {
- tv_end_date.setText(null);
- }
- break;
- }
- }
- }
-
- import java.util.Calendar;
- import java.util.Date;
-
- import android.content.Context;
- import android.graphics.Canvas;
- import android.graphics.Color;
- import android.graphics.Paint;
- import android.graphics.Path;
- import android.graphics.Typeface;
- import android.util.AttributeSet;
- import android.util.Log;
- import android.view.MotionEvent;
- import android.view.View;
-
- public class CalendarView extends View implements View.OnTouchListener {
- private final static String TAG = "anCalendar";
- private Date selectedStartDate;
- private Date selectedEndDate;
- private Date curDate; // 当前日历显示的月
- private Date today; // 今天的日期文字显示红色
- private Date downDate; // 手指按下状态时临时日期
- private Date showFirstDate, showLastDate; // 日历显示的第一个日期和最后一个日期
- private int downIndex; // 按下的格子索引
- private Calendar calendar;
- private Surface surface;
- private int[] date = new int[42]; // 日历显示数字
- private int curStartIndex, curEndIndex; // 当前显示的日历起始的索引
- // private boolean completed = false; // 为false表示只选择了开始日期,true表示结束日期也选择了
- // 给控件设置监听事件
- private OnItemClickListener onItemClickListener;
-
- public CalendarView(Context context) {
- super(context);
- init();
-
- }
-
- public CalendarView(Context context, AttributeSet attrs) {
- super(context, attrs);
- init();
- }
-
- private void init() {
-
- curDate = selectedStartDate = selectedEndDate = today = new Date();
- calendar = Calendar.getInstance();
- calendar.setTime(curDate);
- surface = new Surface();
- surface.density = getResources().getDisplayMetrics().density;
- setBackgroundColor(surface.bgColor);
- setOnTouchListener(this);
- }
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- surface.width = getResources().getDisplayMetrics().widthPixels * 4 / 5;
- surface.height = (int) (getResources().getDisplayMetrics().heightPixels * 2 / 5);
- // if (View.MeasureSpec.getMode(widthMeasureSpec) ==
- // View.MeasureSpec.EXACTLY) {
- // surface.width = View.MeasureSpec.getSize(widthMeasureSpec);
- // }
- // if (View.MeasureSpec.getMode(heightMeasureSpec) ==
- // View.MeasureSpec.EXACTLY) {
- // surface.height = View.MeasureSpec.getSize(heightMeasureSpec);
- // }
- widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(surface.width, View.MeasureSpec.EXACTLY);
- heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(surface.height, View.MeasureSpec.EXACTLY);
- setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- }
-
- @Override
- protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- Log.d(TAG, "[onLayout] changed:" + (changed ? "new size" : "not change") + " left:" + left + " top:" + top + " right:" + right + " bottom:" + bottom);
- if (changed) {
- surface.init();
- }
- super.onLayout(changed, left, top, right, bottom);
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- Log.d(TAG, "onDraw");
- // 画框
- canvas.drawPath(surface.boxPath, surface.borderPaint);
- // 年月
- // String monthText = getYearAndmonth();
- // float textWidth = surface.monthPaint.measureText(monthText);
- // canvas.drawText(monthText, (surface.width - textWidth) / 2f,
- // surface.monthHeight * 3 / 4f, surface.monthPaint);
- // 上一月/下一月
- // canvas.drawPath(surface.preMonthBtnPath,
- // surface.monthChangeBtnPaint);
- // canvas.drawPath(surface.nextMonthBtnPath,
- // surface.monthChangeBtnPaint);
- // 星期
- float weekTextY = surface.monthHeight + surface.weekHeight * 3 / 4f;
- // 星期背景
- // surface.cellBgPaint.setColor(surface.textColor);
- // canvas.drawRect(surface.weekHeight, surface.width,
- // surface.weekHeight, surface.width, surface.cellBgPaint);
- for (int i = 0; i < surface.weekText.length; i++) {
- float weekTextX = i * surface.cellWidth + (surface.cellWidth - surface.weekPaint.measureText(surface.weekText[i])) / 2f;
- canvas.drawText(surface.weekText[i], weekTextX, weekTextY, surface.weekPaint);
- }
-
- // 计算日期
- calculateDate();
- // 按下状态,选择状态背景色
- drawDownOrSelectedBg(canvas);
- // write date number
- // today index
- int todayIndex = -1;
- calendar.setTime(curDate);
- String curYearAndMonth = calendar.get(Calendar.YEAR) + "" + calendar.get(Calendar.MONTH);
- calendar.setTime(today);
- String todayYearAndMonth = calendar.get(Calendar.YEAR) + "" + calendar.get(Calendar.MONTH);
- if (curYearAndMonth.equals(todayYearAndMonth)) {
- int todayNumber = calendar.get(Calendar.DAY_OF_MONTH);
- todayIndex = curStartIndex + todayNumber - 1;
- }
- for (int i = 0; i < 42; i++) {
- int color = surface.textColor;
- if (isLastMonth(i)) {
- color = surface.borderColor;
- } else if (isNextMonth(i)) {
- color = surface.borderColor;
- }
- if (todayIndex != -1 && i == todayIndex) {
- color = surface.todayNumberColor;
- }
- drawCellText(canvas, i, date[i] + "", color);
- }
- super.onDraw(canvas);
- }
-
- private void calculateDate() {
- calendar.setTime(curDate);
- calendar.set(Calendar.DAY_OF_MONTH, 1);
- int dayInWeek = calendar.get(Calendar.DAY_OF_WEEK);
- Log.d(TAG, "day in week:" + dayInWeek);
- int monthStart = dayInWeek;
- if (monthStart == 1) {
- monthStart = 8;
- }
- monthStart -= 1; // 以日为开头-1,以星期一为开头-2
- curStartIndex = monthStart;
- date[monthStart] = 1;
- // last month
- if (monthStart > 0) {
- calendar.set(Calendar.DAY_OF_MONTH, 0);
- int dayInmonth = calendar.get(Calendar.DAY_OF_MONTH);
- for (int i = monthStart - 1; i >= 0; i--) {
- date[i] = dayInmonth;
- dayInmonth--;
- }
- calendar.set(Calendar.DAY_OF_MONTH, date[0]);
- }
- showFirstDate = calendar.getTime();
- // this month
- calendar.setTime(curDate);
- calendar.add(Calendar.MONTH, 1);
- calendar.set(Calendar.DAY_OF_MONTH, 0);
- // Log.d(TAG, "m:" + calendar.get(Calendar.MONTH) + " d:" +
- // calendar.get(Calendar.DAY_OF_MONTH));
- int monthDay = calendar.get(Calendar.DAY_OF_MONTH);
- for (int i = 1; i < monthDay; i++) {
- date[monthStart + i] = i + 1;
- }
- curEndIndex = monthStart + monthDay;
- // next month
- for (int i = monthStart + monthDay; i < 42; i++) {
- date[i] = i - (monthStart + monthDay) + 1;
- }
- if (curEndIndex < 42) {
- // 显示了下一月的
- calendar.add(Calendar.DAY_OF_MONTH, 1);
- }
- calendar.set(Calendar.DAY_OF_MONTH, date[41]);
- showLastDate = calendar.getTime();
- }
-
- /**
- *
- * @param canvas
- * @param index
- * @param text
- */
- private void drawCellText(Canvas canvas, int index, String text, int color) {
- int x = getXByIndex(index);
- int y = getYByIndex(index);
- surface.datePaint.setColor(color);
- float cellY = surface.monthHeight + surface.weekHeight + (y - 1) * surface.cellHeight + surface.cellHeight * 3 / 4f;
- float cellX = (surface.cellWidth * (x - 1)) + (surface.cellWidth - surface.datePaint.measureText(text)) / 2f;
- canvas.drawText(text, cellX, cellY, surface.datePaint);
- }
-
- /**
- *
- * @param canvas
- * @param index
- * @param color
- */
- private void drawCellBg(Canvas canvas, int index, int color) {
- int x = getXByIndex(index);
- int y = getYByIndex(index);
- surface.cellBgPaint.setColor(color);
- float left = surface.cellWidth * (x - 1) + surface.borderWidth;
- float top = surface.monthHeight + surface.weekHeight + (y - 1) * surface.cellHeight + surface.borderWidth;
- canvas.drawRect(left, top, left + surface.cellWidth - surface.borderWidth, top + surface.cellHeight - surface.borderWidth, surface.cellBgPaint);
- }
-
- private void drawDownOrSelectedBg(Canvas canvas) {
- // down and not up
- if (downDate != null) {
- drawCellBg(canvas, downIndex, surface.cellDownColor);
- }
- // selected bg color
- if (!selectedEndDate.before(showFirstDate) && !selectedStartDate.after(showLastDate)) {
- int[] section = new int[] { -1, -1 };
- calendar.setTime(curDate);
- calendar.add(Calendar.MONTH, -1);
- findSelectedIndex(0, curStartIndex, calendar, section);
- if (section[1] == -1) {
- calendar.setTime(curDate);
- findSelectedIndex(curStartIndex, curEndIndex, calendar, section);
- }
- if (section[1] == -1) {
- calendar.setTime(curDate);
- calendar.add(Calendar.MONTH, 1);
- findSelectedIndex(curEndIndex, 42, calendar, section);
- }
- if (section[0] == -1) {
- section[0] = 0;
- }
- if (section[1] == -1) {
- section[1] = 41;
- }
- for (int i = section[0]; i <= section[1]; i++) {
- drawCellBg(canvas, i, surface.cellSelectedColor);
- }
- }
- }
-
- private void findSelectedIndex(int startIndex, int endIndex, Calendar calendar, int[] section) {
- for (int i = startIndex; i < endIndex; i++) {
- calendar.set(Calendar.DAY_OF_MONTH, date[i]);
- Date temp = calendar.getTime();
- // Log.d(TAG, "temp:" + temp.toLocaleString());
- if (temp.compareTo(selectedStartDate) == 0) {
- section[0] = i;
- }
- if (temp.compareTo(selectedEndDate) == 0) {
- section[1] = i;
- return;
- }
- }
- }
-
- public Date getSelectedStartDate() {
- return selectedStartDate;
- }
-
- public Date getSelectedEndDate() {
- return selectedEndDate;
- }
-
- private boolean isLastMonth(int i) {
- if (i < curStartIndex) {
- return true;
- }
- return false;
- }
-
- private boolean isNextMonth(int i) {
- if (i >= curEndIndex) {
- return true;
- }
- return false;
- }
-
- private int getXByIndex(int i) {
- return i % 7 + 1; // 1 2 3 4 5 6 7
- }
-
- private int getYByIndex(int i) {
- return i / 7 + 1; // 1 2 3 4 5 6
- }
-
- // 获得当前应该显示的年月
- public String getYearAndmonth() {
- calendar.setTime(curDate);
- int year = calendar.get(Calendar.YEAR);
- int month = calendar.get(Calendar.MONTH);
- return year + "-" + surface.monthText[month];
- }
-
- // 上一月
- public String clickLeftMonth() {
- calendar.setTime(curDate);
- calendar.add(Calendar.MONTH, -1);
- curDate = calendar.getTime();
- invalidate();
- return getYearAndmonth();
- }
-
- // 下一月
- public String clickRightMonth() {
- calendar.setTime(curDate);
- calendar.add(Calendar.MONTH, 1);
- curDate = calendar.getTime();
- invalidate();
- return getYearAndmonth();
- }
-
- private void setSelectedDateByCoor(float x, float y) {
- // change month
- // if (y < surface.monthHeight) {
- // // pre month
- // if (x < surface.monthChangeWidth) {
- // calendar.setTime(curDate);
- // calendar.add(Calendar.MONTH, -1);
- // curDate = calendar.getTime();
- // }
- // // next month
- // else if (x > surface.width - surface.monthChangeWidth) {
- // calendar.setTime(curDate);
- // calendar.add(Calendar.MONTH, 1);
- // curDate = calendar.getTime();
- // }
- // }
- // cell click down
- if (y > surface.monthHeight + surface.weekHeight) {
- int m = (int) (Math.floor(x / surface.cellWidth) + 1);
- int n = (int) (Math.floor((y - (surface.monthHeight + surface.weekHeight)) / Float.valueOf(surface.cellHeight)) + 1);
- downIndex = (n - 1) * 7 + m - 1;
- Log.d(TAG, "downIndex:" + downIndex);
- calendar.setTime(curDate);
- if (isLastMonth(downIndex)) {
- calendar.add(Calendar.MONTH, -1);
- } else if (isNextMonth(downIndex)) {
- calendar.add(Calendar.MONTH, 1);
- }
- calendar.set(Calendar.DAY_OF_MONTH, date[downIndex]);
- downDate = calendar.getTime();
- }
- invalidate();
- }
-
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- setSelectedDateByCoor(event.getX(), event.getY());
- break;
- case MotionEvent.ACTION_UP:
- if (downDate != null) {
- // if (!completed) {
- // if (downDate.before(selectedStartDate)) {
- // selectedEndDate = selectedStartDate;
- // selectedStartDate = downDate;
- // } else {
- // selectedEndDate = downDate;
- // }
- // completed = true;
- // } else {
- // selectedStartDate = selectedEndDate = downDate;
- // completed = false;
- // }
- selectedStartDate = selectedEndDate = downDate;
- // 响应监听事件
- onItemClickListener.OnItemClick(selectedStartDate);
- // Log.d(TAG, "downdate:" + downDate.toLocaleString());
- // Log.d(TAG, "start:" + selectedStartDate.toLocaleString());
- // Log.d(TAG, "end:" + selectedEndDate.toLocaleString());
- downDate = null;
- invalidate();
- }
- break;
- }
- return true;
- }
-
- // 给控件设置监听事件
- public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
- this.onItemClickListener = onItemClickListener;
- }
-
- // 监听接口
- public interface OnItemClickListener {
- void OnItemClick(Date date);
- }
-
- /**
- *
- * 1. 布局尺寸 2. 文字颜色,大小 3. 当前日期的颜色,选择的日期颜色
- */
- private class Surface {
- public float density;
- public int width; // 整个控件的宽度
- public int height; // 整个控件的高度
- public float monthHeight; // 显示月的高度
- // public float monthChangeWidth; // 上一月、下一月按钮宽度
- public float weekHeight; // 显示星期的高度
- public float cellWidth; // 日期方框宽度
- public float cellHeight; // 日期方框高度
- public float borderWidth;
- public int bgColor = Color.parseColor("#FFFFFF");
- private int textColor = Color.BLACK;
- // private int textColorUnimportant = Color.parseColor("#666666");
- private int btnColor = Color.parseColor("#666666");
- private int borderColor = Color.parseColor("#CCCCCC");
- public int todayNumberColor = Color.RED;
- public int cellDownColor = Color.parseColor("#CCFFFF");
- public int cellSelectedColor = Color.parseColor("#99CCFF");
- public Paint borderPaint;
- public Paint monthPaint;
- public Paint weekPaint;
- public Paint datePaint;
- public Paint monthChangeBtnPaint;
- public Paint cellBgPaint;
- public Path boxPath; // 边框路径
- // public Path preMonthBtnPath; // 上一月按钮三角形
- // public Path nextMonthBtnPath; // 下一月按钮三角形
- public String[] weekText = { "日", "一", "二", "三", "四", "五", "六" };
- public String[] monthText = { "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月" };
-
- public void init() {
- float temp = height / 7f;
- monthHeight = 0;// (float) ((temp + temp * 0.3f) * 0.6);
- // monthChangeWidth = monthHeight * 1.5f;
- weekHeight = (float) ((temp + temp * 0.3f) * 0.7);
- cellHeight = (height - monthHeight - weekHeight) / 6f;
- cellWidth = width / 7f;
- borderPaint = new Paint();
- borderPaint.setColor(borderColor);
- borderPaint.setStyle(Paint.Style.STROKE);
- borderWidth = (float) (0.5 * density);
- // Log.d(TAG, "borderwidth:" + borderWidth);
- borderWidth = borderWidth < 1 ? 1 : borderWidth;
- borderPaint.setStrokeWidth(borderWidth);
- monthPaint = new Paint();
- monthPaint.setColor(textColor);
- monthPaint.setAntiAlias(true);
- float textSize = cellHeight * 0.4f;
- Log.d(TAG, "text size:" + textSize);
- monthPaint.setTextSize(textSize);
- monthPaint.setTypeface(Typeface.DEFAULT_BOLD);
- weekPaint = new Paint();
- weekPaint.setColor(textColor);
- weekPaint.setAntiAlias(true);
- float weekTextSize = weekHeight * 0.6f;
- weekPaint.setTextSize(weekTextSize);
- weekPaint.setTypeface(Typeface.DEFAULT_BOLD);
- datePaint = new Paint();
- datePaint.setColor(textColor);
- datePaint.setAntiAlias(true);
- float cellTextSize = cellHeight * 0.5f;
- datePaint.setTextSize(cellTextSize);
- datePaint.setTypeface(Typeface.DEFAULT_BOLD);
- boxPath = new Path();
- // boxPath.addRect(0, 0, width, height, Direction.CW);
- // boxPath.moveTo(0, monthHeight);
- boxPath.rLineTo(width, 0);
- boxPath.moveTo(0, monthHeight + weekHeight);
- boxPath.rLineTo(width, 0);
- for (int i = 1; i < 6; i++) {
- boxPath.moveTo(0, monthHeight + weekHeight + i * cellHeight);
- boxPath.rLineTo(width, 0);
- boxPath.moveTo(i * cellWidth, monthHeight);
- boxPath.rLineTo(0, height - monthHeight);
- }
- boxPath.moveTo(6 * cellWidth, monthHeight);
- boxPath.rLineTo(0, height - monthHeight);
- // preMonthBtnPath = new Path();
- // int btnHeight = (int) (monthHeight * 0.6f);
- // preMonthBtnPath.moveTo(monthChangeWidth / 2f, monthHeight / 2f);
- // preMonthBtnPath.rLineTo(btnHeight / 2f, -btnHeight / 2f);
- // preMonthBtnPath.rLineTo(0, btnHeight);
- // preMonthBtnPath.close();
- // nextMonthBtnPath = new Path();
- // nextMonthBtnPath.moveTo(width - monthChangeWidth / 2f,
- // monthHeight / 2f);
- // nextMonthBtnPath.rLineTo(-btnHeight / 2f, -btnHeight / 2f);
- // nextMonthBtnPath.rLineTo(0, btnHeight);
- // nextMonthBtnPath.close();
- monthChangeBtnPaint = new Paint();
- monthChangeBtnPaint.setAntiAlias(true);
- monthChangeBtnPaint.setStyle(Paint.Style.FILL_AND_STROKE);
- monthChangeBtnPaint.setColor(btnColor);
- cellBgPaint = new Paint();
- cellBgPaint.setAntiAlias(true);
- cellBgPaint.setStyle(Paint.Style.FILL);
- cellBgPaint.setColor(cellSelectedColor);
- }
- }
-
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。