android自定义view显示日历

自定义view主要代码,

通过监听手势实现左右滑动的效果

package com.uwatch.condor.view;



import java.util.Calendar;


import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.view.View;


import com.uwatch.condor.R;
import com.uwatch.condor.util.DateRange;
import com.uwatch.condor.util.Util;


public class CalendarView extends View implements OnGestureListener {
private String TAG = "CalendarView";
private Context mContext;
private String mMonths[];
private String mWeeks[];
private Paint mTitlePaint;
private Paint mCirclePaint;
private Rect mTitleRect;
private int mFirstDayofWeek;//本月第一天是星期几
private int mLastDayofWeek;//本月最后一天是星期几
private int mMonthDays;//本月总共多少天
private DateRange mDateRange;
private int mRows;
private float dtitle ;
private float rowHeight;
private int mCurSeleted;
private GestureDetector mDetector;
private int direction;
private int mCurrDay;
private int mCurrYear;
private int mCurrMonth;
private boolean isCurrMonth;


private OnCalendarViewListener mOnCalendarViewListener;






public CalendarView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}


public CalendarView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}


public CalendarView(Context context) {
super(context);
init(context);
}


public void init(Context context){
mContext = context;
mMonths = mContext.getResources().getStringArray(R.array.month_value);
mWeeks = mContext.getResources().getStringArray(R.array.week_value);
mDateRange = DateRange.getInstance();
dtitle = 0;
rowHeight = 0;
isCurrMonth = true;


mTitlePaint = new Paint();
mTitlePaint.setAntiAlias(true);
mTitlePaint.setStyle(Style.FILL);


mTitlePaint.setStrokeWidth(Util.dp2px(mContext, 2));


mTitleRect = new Rect();


mCirclePaint = new Paint();
mCirclePaint.setColor(0xff91b716);
mCirclePaint.setAntiAlias(true);
mCirclePaint.setStyle(Style.FILL);


mDetector = new GestureDetector(mContext, this);


mCurSeleted = Util.getDayOfMonth(mDateRange.getCurrDate());
/*setCurrMonthInfo(mDateRange);
redraw(mDateRange.getCurrDate());*/
}


@Override
protected void onDraw(Canvas canvas) {
if(getWidth()>0 && getHeight()>0){
if(dtitle == 0){
dtitle = getWidth()*1.0f/mWeeks.length;
}
//setCurrMonthInfo(mDateRange);
drawTitle(canvas);
drawDays(canvas);
}
super.onDraw(canvas);
}


public void drawTitle(Canvas canvas){
mTitlePaint.setTextSize(Util.sp2px(mContext, 15));
mTitlePaint.setColor(0xff3a3a3a);
for(int i=0;i<mWeeks.length;i++){
mTitlePaint.getTextBounds(mWeeks[i], 0, mWeeks[i].length(), mTitleRect);
canvas.drawText(mWeeks[i], dtitle*i+(dtitle-mTitleRect.width())/2, mTitleRect.height()*1.5f, mTitlePaint);
}
mTitlePaint.setColor(0xff4FC1E9);
canvas.drawLine(0, mTitleRect.height()*2, getWidth(), mTitleRect.height()*2, mTitlePaint);
canvas.drawLine(0, getHeight(), getWidth(), getHeight(), mTitlePaint);


}


public void setSelectedIndex(int index){


}

///绘制日期主要代码
public void drawDays(Canvas canvas){
rowHeight= (getHeight() - mTitleRect.height()*2)*1.0f/mRows;
mTitlePaint.setColor(0xff9a9a9a);
mTitlePaint.setTextSize(Util.sp2px(mContext, 15));
int currrow = 1;
Rect rect = new Rect();
for(int i=1;i<=mMonthDays;i++){
mTitlePaint.getTextBounds(Util.getDay(i), 0, Util.getDay(i).length(), rect);


if(i == mCurSeleted){
if((i+mFirstDayofWeek-1)%7 != 0){
canvas.drawCircle(dtitle*((i+mFirstDayofWeek-1)%7) - dtitle/2,rowHeight*(currrow) - rowHeight/2 +mTitleRect.height()*2+Util.dp2px(mContext, 2), rowHeight*3/8, mCirclePaint);
}else{
canvas.drawCircle(dtitle*(7) - dtitle/2,rowHeight*(currrow) - rowHeight/2 +mTitleRect.height()*2+Util.dp2px(mContext, 2), rowHeight*3/8, mCirclePaint);
}


mTitlePaint.setColor(0xffffffff);
}
if(isCurrMonth){
if(i <= mCurrDay){
mTitlePaint.setColor(0xff4d4d4d);
}else{
mTitlePaint.setColor(0xff9d9d9d);
}
}else{
mTitlePaint.setColor(0xff4d4d4d);
}
if((i+mFirstDayofWeek - 1)%7==0){
canvas.drawText(Util.getDay(i), dtitle*6 + (dtitle - rect.width())/2, 
rowHeight*(currrow) -(rowHeight - rect.height())/2+mTitleRect.height()*2+Util.dp2px(mContext, 2), mTitlePaint);
}else{
canvas.drawText(Util.getDay(i), dtitle*((i+mFirstDayofWeek-1)%7 -1 ) + (dtitle - rect.width())/2, 
rowHeight*(currrow) -(rowHeight - rect.height())/2+mTitleRect.height()*2+Util.dp2px(mContext, 2), mTitlePaint);
}


if((i+mFirstDayofWeek-1) % 7 == 0){
currrow++;
}
}
}



public void setOnCalendarViewListener(OnCalendarViewListener listener){
this.mOnCalendarViewListener = listener;
}


public void setDateRange(DateRange dtr){
this.mDateRange = dtr;
mCurSeleted = Util.getDayOfMonth(dtr.getCurrDate());
isCurrMonth = isCurrentMonth(dtr);
redraw(dtr.getCurrDate());
}


public boolean isCurrentMonth(DateRange dtr){
if(Util.getYear(dtr.getCurrDate()) == mCurrYear && Util.getMonth(dtr.getCurrDate()) == mCurrMonth){
return true;
}else{
return false;
}
}


public void setCurrMonthInfo(DateRange dtr){
Calendar calendar = Calendar.getInstance();
mCurrDay = calendar.get(Calendar.DAY_OF_MONTH);
mCurrMonth = calendar.get(Calendar.MONTH);
mCurrYear = calendar.get(Calendar.YEAR);


isCurrMonth = isCurrentMonth(dtr);
if(!isCurrMonth)
if((Util.stringToDate(dtr.getCurrDate(), "yyyy-MM-dd").getTime())
>(Util.stringToDate(Util.dateToString(calendar.getTime(), "yyyy-MM-dd"), "yyyy-MM-dd")).getTime()){
dtr.SetPara(mCurrYear, mCurrMonth, mCurrDay);
this.mDateRange = dtr;
setDateRange(this.mDateRange);
mOnCalendarViewListener.setDateRange(mDateRange);
isCurrMonth = true;
}


}


public void redraw(String date){
mMonthDays = Util.getMonthDays(date);
mFirstDayofWeek = Util.getDayOfWeek(Util.getFirstDay(date));
mLastDayofWeek = Util.getDayOfWeek(Util.getLastDay(date));


mRows = (mMonthDays+mFirstDayofWeek-1) / 7;
if(mMonthDays+mFirstDayofWeek-1>mRows*7){
mRows = mRows+1;
}
invalidate();
}


public interface OnCalendarViewListener {
public void setDateRange(DateRange dtrange);
public void dismissCal();
}


@Override
public boolean onTouchEvent(MotionEvent event) {
return mDetector.onTouchEvent(event);
}


@Override
public boolean onDown(MotionEvent e) {
return true;
}


@Override
public void onShowPress(MotionEvent e) {


}


@Override
public boolean onSingleTapUp(MotionEvent e) {
float x = e.getX();
float y = e.getY();
int r = 0;
int v = 0;
for(int i = 0;i<y;i++){
if(x>i*dtitle && x<(i+1)*dtitle){
r = i+1;
break;
}
}
for(int i=0;i<mRows;i++){
if(y>i*rowHeight+mTitleRect.height()*2+Util.dp2px(mContext, 2)
&& y<(i+1)*rowHeight+mTitleRect.height()*2+Util.dp2px(mContext, 2)){
v = i+1;
break;
}
}
if(getDay(r,v) > 0 && getDay(r,v)<=mMonthDays){
if(getDay(r,v)>mCurrDay && isCurrentMonth(mDateRange)){
return false;
}
mCurSeleted = getDay(r,v);
String[] dt = mDateRange.getCurrDate().split("-");
DateRange dr = DateRange.getInstance();
dr.SetPara(Integer.valueOf(dt[0]), Integer.valueOf(dt[1]), mCurSeleted);
//mOnCalendarViewListener.setDateRange(dr);
invalidate();
}


return false;
}


public int getDay(int r,int v){


int total = (v -1)*7+r;
if(total > mMonthDays+mFirstDayofWeek-1){
return 0;
}


return total - mFirstDayofWeek+1;
}


@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY) {
// TODO Auto-generated method stub
return true;
}


@Override
public void onLongPress(MotionEvent e) {
// TODO Auto-generated method stub


}


@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
float dx = e1.getX() - e2.getX();
float dy = e1.getY() - e2.getY();
float r = Math.abs(dx) / Math.abs(dy);
if(r>1){
if(dx<0){
getDateRange(mDateRange,-1);
}else{
getDateRange(mDateRange,1);
}
}else{
if(dy>0){
String[] dt = mDateRange.getCurrDate().split("-");
DateRange dr = DateRange.getInstance();
dr.SetPara(Integer.valueOf(dt[0]), Integer.valueOf(dt[1]), mCurSeleted);
mOnCalendarViewListener.setDateRange(dr);
mOnCalendarViewListener.dismissCal();
}
}
return false;
}


private void getDateRange(DateRange dr, int direct) {
String date = dr.getCurrDate();
int year = Util.getYear(date);
int month = Util.getMonth(date);
//int day = Util.getDayOfMonth(date);
month = month + direct;
if (month < 0) {
year = year - 1;
month = 11;
} else if (month > 11) {
year = year + 1;
month = 0;
}


Calendar calendar = Calendar.getInstance();


int curryear = calendar.get(Calendar.YEAR);
int currmonth = calendar.get(Calendar.MONTH);
int currday = calendar.get(Calendar.DAY_OF_MONTH);


if (year > curryear) {
return;
}


if (year == curryear && month > currmonth) {
return;
}


int days = Util.getMonthDays(year + "-" + Util.getDay(month + 1)
+ "-01");
if (days < mCurSeleted) {
mCurSeleted = days;
}


if(month == currmonth){
if(currday<mCurSeleted){
mCurSeleted = currday;
}
}
dr.SetPara(year, month + 1, mCurSeleted);
mOnCalendarViewListener.setDateRange(dr);
setDateRange(dr);
}


public int getCurrSlected(){
return this.mCurSeleted;
}


public void setCurrSelected(int days) {
this.mCurSeleted = days;


}


}



以下为上述代码中使用到的工具类


package com.uwatch.condor.util;


import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;


import com.uwatch.condor.bll.UserBLL;
import com.uwatch.condor.btconnect.BTConnectApplication;


import android.content.Context;
import android.util.Log;


public class Util {
private static String TAG= "Util";

sp转换成像素
public static int sp2px(Context context, float spValue) { 
final float fontScale = context.getResources().getDisplayMetrics().scaledDensity; 
return (int) (spValue * fontScale + 0.5f); 
}

///dp转像素

public static int dp2px(Context context, float dipValue) { 
final float scale = context.getResources().getDisplayMetrics().density; 
return (int) (dipValue * scale + 0.5f); 
}

public static Date stringToDate(String date,String fm){
SimpleDateFormat format = new SimpleDateFormat(fm);
try {
Date dt = format.parse(date);
return dt;
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}

public static String longToDateString(long time,String fm){
Date date = new Date(time);
return dateToString(date, fm);
}

public static String dateToString(Date date,String fm){
SimpleDateFormat format = new SimpleDateFormat(fm);
return format.format(date);
}

public static String calFloat(float value,int count){
BigDecimal bd = new BigDecimal(value+"");
bd = bd.setScale(count,BigDecimal.ROUND_HALF_UP);
return bd.toString();
}


public static int getMonthDays(String date){
Date dt = stringToDate(date, "yyyy-MM-dd");
Calendar calendar = Calendar.getInstance();
calendar.setTime(dt);
return calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
}


public static int getDayOfMonth(String date){
Date dt = stringToDate(date, "yyyy-MM-dd");
Calendar calendar = Calendar.getInstance();
calendar.setTime(dt);
return calendar.get(Calendar.DAY_OF_MONTH);
}


public static int getDayOfWeek(String date){
Date dt = stringToDate(date, "yyyy-MM-dd");
Calendar calendar = Calendar.getInstance();
calendar.setTime(dt);
return calendar.get(Calendar.DAY_OF_WEEK);
}


public static int getYear(String date){
Date dt = stringToDate(date, "yyyy-MM-dd");
Calendar calendar = Calendar.getInstance();
calendar.setTime(dt);
return calendar.get(Calendar.YEAR);
}


public static int getMonth(String date){
Date dt = stringToDate(date, "yyyy-MM-dd");
Calendar calendar = Calendar.getInstance();
calendar.setTime(dt);
return calendar.get(Calendar.MONTH);
}


public static String getFirstDay(String date){
Date dt = stringToDate(date, "yyyy-MM-dd");
Calendar calendar = Calendar.getInstance();
calendar.setTime(dt);
calendar.set(Calendar.DAY_OF_MONTH, 1);
Date d = calendar.getTime();
return dateToString(d, "yyyy-MM-dd");
}


public static String getLastDay(String date){
Date dt = stringToDate(date, "yyyy-MM-dd");
Calendar calendar = Calendar.getInstance();
calendar.setTime(dt);
calendar.set(Calendar.DAY_OF_MONTH,getMonthDays(date));
Date d = calendar.getTime();
return dateToString(d, "yyyy-MM-dd");
}


}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

释汐宇辰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值