Open wanglu123run opened 7 years ago
package cn.aigestudio.datepicker.views;
import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.annotation.TargetApi; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.Region; import android.graphics.drawable.ShapeDrawable; import android.graphics.drawable.shapes.OvalShape; import android.os.Build; import android.os.Parcelable; import android.text.TextUtils; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.animation.AccelerateInterpolator; import android.view.animation.DecelerateInterpolator; import android.widget.Scroller;
import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map;
import cn.aigestudio.datepicker.bizs.calendars.DPCManager; import cn.aigestudio.datepicker.bizs.calendars.DPCNCalendar; import cn.aigestudio.datepicker.bizs.decors.DPDecor; import cn.aigestudio.datepicker.bizs.themes.DPTManager; import cn.aigestudio.datepicker.cons.DPMode; import cn.aigestudio.datepicker.entities.DPInfo;
/**
@author AigeStudio 2015-06-29 */ public class MonthView extends View {
private boolean isVer=false;//是否可以垂直滑动
private final Region[][] MONTH_REGIONS_4 = new Region[4][7]; private final Region[][] MONTH_REGIONS_5 = new Region[5][7]; private final Region[][] MONTH_REGIONS_6 = new Region[6][7];
private final DPInfo[][] INFO_4 = new DPInfo[4][7]; private final DPInfo[][] INFO_5 = new DPInfo[5][7]; private final DPInfo[][] INFO_6 = new DPInfo[6][7];
private final Map<String, List
private DPCManager mCManager = DPCManager.getInstance(); private DPTManager mTManager = DPTManager.getInstance();
protected Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG | Paint.LINEAR_TEXT_FLAG); private Scroller mScroller; private DecelerateInterpolator decelerateInterpolator = new DecelerateInterpolator(); private AccelerateInterpolator accelerateInterpolator = new AccelerateInterpolator(); private OnDateChangeListener onDateChangeListener; private DatePicker.OnDatePickedListener onDatePickedListener; private ScaleAnimationListener scaleAnimationListener;
private DPMode mDPMode = DPMode.MULTIPLE; private SlideMode mSlideMode; private DPDecor mDPDecor;
private int circleRadius; private int indexYear, indexMonth; private int centerYear, centerMonth; private int leftYear, leftMonth; private int rightYear, rightMonth; private int topYear, topMonth; private int bottomYear, bottomMonth; private int width, height; private int sizeDecor, sizeDecor2x, sizeDecor3x; private int lastPointX, lastPointY; private int lastMoveX, lastMoveY; private int criticalWidth, criticalHeight; private int animZoomOut1, animZoomIn1, animZoomOut2;
private float sizeTextGregorian, sizeTextFestival; private float offsetYFestival1, offsetYFestival2;
private boolean isNewEvent, isFestivalDisplay = true, isHolidayDisplay = true, isTodayDisplay = true, isDeferredDisplay = true;
private Map<String, BGCircle> cirApr = new HashMap<>(); private Map<String, BGCircle> cirDpr = new HashMap<>();
private List
/ 是否拦截横向滑动 listview中有用/ private boolean isInterceptLateral;
public void setIsInterceptLateral(boolean b) { isInterceptLateral=b; }
public MonthView(Context context) { super(context); init(context); }
public MonthView(Context context, AttributeSet attrs) { super(context, attrs); init(context); }
private void init(Context context) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { scaleAnimationListener = new ScaleAnimationListener(); } mScroller = new Scroller(context); mPaint.setTextAlign(Paint.Align.CENTER); }
@Override protected Parcelable onSaveInstanceState() { return super.onSaveInstanceState(); }
@Override protected void onRestoreInstanceState(Parcelable state) { super.onRestoreInstanceState(state); }
@Override public void computeScroll() { // Log.e("---","--------mScroller.isFinished()------------"+mScroller.isFinished());//true是结束了 false是进行中 // Log.e("---","--------mScroller.computeScrollOffset()------------"+mScroller.computeScrollOffset());//true是结束了 false是进行中 if (mScroller.computeScrollOffset()) {//动画执行完成后会返回返加true // 停止滑动后,滑动到指定位置 Log.e("---","--------computeScroll------------invalidate"); scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); } else { //滑动中 Log.e("---","--------computeScroll------------requestLayout"); if (isTouch) { requestLayout(); } } }
private boolean isTouch=false; @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: mScroller.forceFinished(true); mSlideMode = null; isNewEvent = true; lastPointX = (int) event.getX(); lastPointY = (int) event.getY(); break; case MotionEvent.ACTION_MOVE: isTouch=true; if (isNewEvent) { if (Math.abs(lastPointX - event.getX()) > 100) { mSlideMode = SlideMode.HOR; isNewEvent = false; } else if (Math.abs(lastPointY - event.getY()) > 50&&isVer) { mSlideMode = SlideMode.VER; isNewEvent = false; } } if (mSlideMode == SlideMode.HOR) { //x=开始坐标-当前坐标+(view宽度月份索引) y=哪一年高度 int totalMoveX = (int) (lastPointX - event.getX()) + lastMoveX; smoothScrollTo(totalMoveX, indexYear height); if (isInterceptLateral) { getParent().requestDisallowInterceptTouchEvent(true); } // Log.e("-------","-------------smoothScrollTo111-------------"); } else if (mSlideMode == SlideMode.VER&&isVer) { int totalMoveY = (int) (lastPointY - event.getY()) + lastMoveY; smoothScrollTo(width indexMonth, totalMoveY); // Log.e("-------","-------------smoothScrollTo222-------------"); } break; case MotionEvent.ACTION_UP: isTouch=false; if (mSlideMode == SlideMode.VER&&isVer) { if (Math.abs(lastPointY - event.getY()) > 25) { if (lastPointY < event.getY()) { if (Math.abs(lastPointY - event.getY()) >= criticalHeight) { indexYear--; centerYear = centerYear - 1; } } else if (lastPointY > event.getY()) { if (Math.abs(lastPointY - event.getY()) >= criticalHeight) { indexYear++; centerYear = centerYear + 1; } } buildRegion(); computeDate(); smoothScrollTo(width indexMonth, height indexYear); lastMoveY = height indexYear; } else { defineRegion((int) event.getX(), (int) event.getY()); } } else if (mSlideMode == SlideMode.HOR) { if (Math.abs(lastPointX - event.getX()) > 25) { if (lastPointX > event.getX() && Math.abs(lastPointX - event.getX()) >= criticalWidth) { indexMonth++; centerMonth = (centerMonth + 1) % 13; if (centerMonth == 0) { centerMonth = 1; centerYear++; } } else if (lastPointX < event.getX() && Math.abs(lastPointX - event.getX()) >= criticalWidth) { indexMonth--; centerMonth = (centerMonth - 1) % 12; if (centerMonth == 0) { centerMonth = 12; centerYear--; } } buildRegion(); computeDate(); smoothScrollTo(width indexMonth, indexYear height); lastMoveX = width indexMonth; } else { defineRegion((int) event.getX(), (int) event.getY()); } } else { defineRegion((int) event.getX(), (int) event.getY()); } break; } return true; }
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int measureWidth = MeasureSpec.getSize(widthMeasureSpec); setMeasuredDimension(measureWidth, (int) (measureWidth * 6F / 7F)); }
@Override protected void onSizeChanged(int w, int h, int oldW, int oldH) { width = w; height = h;
criticalWidth = (int) (1F / 5F * width);
criticalHeight = (int) (1F / 5F * height);
int cellW = (int) (w / 7F);
int cellH4 = (int) (h / 4F);
int cellH5 = (int) (h / 5F);
int cellH6 = (int) (h / 6F);
circleRadius = cellW;
animZoomOut1 = (int) (cellW * 1.2F);
animZoomIn1 = (int) (cellW * 0.8F);
animZoomOut2 = (int) (cellW * 1.1F);
sizeDecor = (int) (cellW / 3F);
sizeDecor2x = sizeDecor * 2;
sizeDecor3x = sizeDecor * 3;
sizeTextGregorian = width / 20F;
mPaint.setTextSize(sizeTextGregorian);
float heightGregorian = mPaint.getFontMetrics().bottom - mPaint.getFontMetrics().top;
sizeTextFestival = width / 40F;
mPaint.setTextSize(sizeTextFestival);
float heightFestival = mPaint.getFontMetrics().bottom - mPaint.getFontMetrics().top;
offsetYFestival1 = (((Math.abs(mPaint.ascent() + mPaint.descent())) / 2F) +
heightFestival / 2F + heightGregorian / 2F) / 2F;
offsetYFestival2 = offsetYFestival1 * 2F;
for (int i = 0; i < MONTH_REGIONS_4.length; i++) {
for (int j = 0; j < MONTH_REGIONS_4[i].length; j++) {
Region region = new Region();
region.set((j * cellW), (i * cellH4), cellW + (j * cellW),
cellW + (i * cellH4));
MONTH_REGIONS_4[i][j] = region;
}
}
for (int i = 0; i < MONTH_REGIONS_5.length; i++) {
for (int j = 0; j < MONTH_REGIONS_5[i].length; j++) {
Region region = new Region();
region.set((j * cellW), (i * cellH5), cellW + (j * cellW),
cellW + (i * cellH5));
MONTH_REGIONS_5[i][j] = region;
}
}
for (int i = 0; i < MONTH_REGIONS_6.length; i++) {
for (int j = 0; j < MONTH_REGIONS_6[i].length; j++) {
Region region = new Region();
region.set((j * cellW), (i * cellH6), cellW + (j * cellW),
cellW + (i * cellH6));
MONTH_REGIONS_6[i][j] = region;
}
}
}
private boolean isCurrentMonth=false; private Canvas mCanvas; @Override protected void onDraw(Canvas canvas) { mCanvas=canvas; canvas.drawColor(mTManager.colorBG()); /**
private boolean isDisplaySelectColor=false;//是否显示选中颜色
/**
/**
/**
@param rect */ private void drawSelectBGColor(String str, boolean isWeekend, boolean isF, Rect rect) { // invalidate(); if (!isDisplaySelectColor||mCanvas==null||!isCurrentMonth) { return; } /**
是否选中了 */ if (isTextSelecterColor) { if (isF) { //农历 if (isTextSelecterColor) { String data=centerYear+"-"+centerMonth+"-"+mCManager.obtainDPInfo(centerYear, centerMonth)[selectI][selectJ].strG+"-"+str; if (data.equals(mData)) { mPaint.setColor(mTManager.textColorSelected()); } } } else { //公历 String data=centerYear+"-"+centerMonth+"-"+str+"-"+mCManager.obtainDPInfo(centerYear, centerMonth)[selectI][selectJ].strF;
if (data.equals(mData)) {
// mPaint.setColor(mTManager.textColorSelected()); // Log.e("","-----------------------data:"+data); // Log.e("----", "---------------------mData:" + mData); mPaint.setColor(Color.parseColor("#fffff2ed")); mCanvas.drawCircle(rect.centerX(), rect.centerY(), circleRadius / 1.7F, mPaint);
mPaint.setColor(Color.parseColor("#ffffdbd0"));
mCanvas.drawCircle(rect.centerX(), rect.centerY(), circleRadius / 1.8F, mPaint);
mPaint.setColor(Color.parseColor("#ffffcebe"));
mCanvas.drawCircle(rect.centerX(), rect.centerY(), circleRadius / 1.9F, mPaint);
mPaint.setColor(Color.parseColor("#ffff4301"));
mCanvas.drawCircle(rect.centerX(), rect.centerY(), circleRadius / 2F, mPaint);
}
} } }
/**
private void drawClickBGCircle(Canvas canvas, BGCircle circle) { canvas.save(); canvas.translate(circle.getX() - circle.getRadius() / 2, circle.getY() - circle.getRadius() / 2); circle.getShape().getShape().resize(circle.getRadius(), circle.getRadius()); circle.getShape().draw(canvas); canvas.restore(); }
/**
private void draw(Canvas canvas, int x, int y, int year, int month) { // Log.e("----", "---------------------year+month:" + year+"-----"+month); canvas.save(); canvas.translate(x, y); DPInfo[][] info = mCManager.obtainDPInfo(year, month); DPInfo[][] result; Region[][] tmp; if (TextUtils.isEmpty(info[4][0].strG)) { tmp = MONTH_REGIONS_4; arrayClear(INFO_4); result = arrayCopy(info, INFO_4); } else if (TextUtils.isEmpty(info[5][0].strG)) { tmp = MONTH_REGIONS_5; arrayClear(INFO_5); result = arrayCopy(info, INFO_5); } else { tmp = MONTH_REGIONS_6; arrayClear(INFO_6); result = arrayCopy(info, INFO_6); } // Log.e("----", "---------------------result.length:" + result.length); for (int i = 0; i < result.length; i++) { for (int j = 0; j < result[i].length; j++) { draw(canvas, tmp[i][j].getBounds(), info[i][j]); } } canvas.restore(); }
private void draw(Canvas canvas, Rect rect, DPInfo info) { drawBG(canvas, rect, info); drawGregorian(canvas, rect, info.strG, info.isWeekend); if (isFestivalDisplay) drawFestival(canvas, rect, info.strF, info.isFestival, info.strG); drawDecor(canvas, rect, info); }
private void drawBG(Canvas canvas, Rect rect, DPInfo info) { if (null != mDPDecor && info.isDecorBG) { /**
/**
@param rect / private void drawBGToday(Canvas canvas, Rect rect) { / mPaint.setColor(mTManager.colorToday()); canvas.drawCircle(rect.centerX(), rect.centerY(), circleRadius / 2F, mPaint);*/
mPaint.setColor(Color.parseColor("#fffff2ed")); canvas.drawCircle(rect.centerX(), rect.centerY(), circleRadius / 1.7F, mPaint);
mPaint.setColor(Color.parseColor("#ffffdbd0")); canvas.drawCircle(rect.centerX(), rect.centerY(), circleRadius / 1.8F, mPaint);
mPaint.setColor(Color.parseColor("#ffffcebe")); canvas.drawCircle(rect.centerX(), rect.centerY(), circleRadius / 1.9F, mPaint);
mPaint.setColor(Color.parseColor("#ffff4301")); canvas.drawCircle(rect.centerX(), rect.centerY(), circleRadius / 2F, mPaint); }
/**
/**
/**
@param isWeekend */ private void drawGregorian(Canvas canvas, Rect rect, String str, boolean isWeekend) { // Log.e("----", "---------------------str:" + str); mPaint.setTextSize(sizeTextGregorian); /**
} drawSelectBGColor(str,isWeekend,false,rect); drawSelectTextColor(str,isWeekend,false); float y = rect.centerY(); if (!isFestivalDisplay) y = rect.centerY() + Math.abs(mPaint.ascent()) - (mPaint.descent() - mPaint.ascent()) / 2F; canvas.drawText(str, rect.centerX(), y, mPaint); }
/**
/**
List
void setOnDateChangeListener(OnDateChangeListener onDateChangeListener) { this.onDateChangeListener = onDateChangeListener; }
public void setOnDatePickedListener(DatePicker.OnDatePickedListener onDatePickedListener) { this.onDatePickedListener = onDatePickedListener; }
void setDPMode(DPMode mode) { this.mDPMode = mode; }
void setDPDecor(DPDecor decor) { this.mDPDecor = decor; }
DPMode getDPMode() { return mDPMode; }
void setDate(int year, int month) { centerYear = year; centerMonth = month; indexYear = 0; indexMonth = 0; buildRegion(); computeDate(); requestLayout(); invalidate(); }
/**
}
void setFestivalDisplay(boolean isFestivalDisplay) { this.isFestivalDisplay = isFestivalDisplay; }
void setTodayDisplay(boolean isTodayDisplay) { this.isTodayDisplay = isTodayDisplay; }
void setHolidayDisplay(boolean isHolidayDisplay) { this.isHolidayDisplay = isHolidayDisplay; }
void setDeferredDisplay(boolean isDeferredDisplay) { this.isDeferredDisplay = isDeferredDisplay; }
private void smoothScrollTo(int fx, int fy) { int dx = fx - mScroller.getFinalX(); int dy = fy - mScroller.getFinalY(); smoothScrollBy(dx, dy); }
private void smoothScrollBy(int dx, int dy) { mScroller.startScroll(mScroller.getFinalX(), mScroller.getFinalY(), dx, dy, 500); invalidate(); }
/**
private void buildRegion() {
String key = indexYear + ":" + indexMonth;
if (!REGION_SELECTED.containsKey(key)) {
REGION_SELECTED.put(key, new ArrayList
private void arrayClear(DPInfo[][] info) { for (DPInfo[] anInfo : info) { Arrays.fill(anInfo, null); } }
private DPInfo[][] arrayCopy(DPInfo[][] src, DPInfo[][] dst) { for (int i = 0; i < dst.length; i++) { System.arraycopy(src[i], 0, dst[i], 0, dst[i].length); } return dst; }
private boolean isPlayAnimain=false;//点击是否显示动画效果 private boolean isTextSelecterColor=false;//是否触发绘制选中 private String mData="";//当前选中的日期 private int selectI; private int selectJ;
/**
@param y */ private void defineRegion(int x, int y) { DPInfo[][] info = mCManager.obtainDPInfo(centerYear, centerMonth); Region[][] tmp; if (TextUtils.isEmpty(info[4][0].strG)) { tmp = MONTH_REGIONS_4; } else if (TextUtils.isEmpty(info[5][0].strG)) { tmp = MONTH_REGIONS_5; } else { tmp = MONTH_REGIONS_6; } for (int i = 0; i < tmp.length; i++) { for (int j = 0; j < tmp[i].length; j++) { Region region = tmp[i][j]; if (TextUtils.isEmpty(mCManager.obtainDPInfo(centerYear, centerMonth)[i][j].strG)) { continue; } /**
判断点击的位置是否属于这个区域
/
if (region.contains(x, y)) {
List
ValueAnimator animScale2 =
ObjectAnimator.ofInt(circle, "radius", animZoomOut1, animZoomIn1);
animScale2.setDuration(100);
animScale2.setInterpolator(accelerateInterpolator);
animScale2.addUpdateListener(scaleAnimationListener);
ValueAnimator animScale3 =
ObjectAnimator.ofInt(circle, "radius", animZoomIn1, animZoomOut2);
animScale3.setDuration(150);
animScale3.setInterpolator(decelerateInterpolator);
animScale3.addUpdateListener(scaleAnimationListener);
ValueAnimator animScale4 =
ObjectAnimator.ofInt(circle, "radius", animZoomOut2, circleRadius);
animScale4.setDuration(50);
animScale4.setInterpolator(accelerateInterpolator);
animScale4.addUpdateListener(scaleAnimationListener);
AnimatorSet animSet = new AnimatorSet();
animSet.playSequentially(animScale1, animScale2, animScale3, animScale4);
// animSet.playSequentially(animScale1); animSet.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { / 单选点击 / if (null != onDatePickedListener) { onDatePickedListener.onDatePicked(date); } } }); animSet.start(); } cirApr.put(date, circle); } else { BGCircle circle = createCircle( region.getBounds().centerX() + indexMonth width, region.getBounds().centerY() + indexYear height); / 单选点击 / if (null != onDatePickedListener) { onDatePickedListener.onDatePicked(date); } /if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { ValueAnimator animScale1 =ObjectAnimator.ofInt(circle, "radius", 0, animZoomOut1); animScale1.setDuration(50); animScale1.setInterpolator(decelerateInterpolator); animScale1.addUpdateListener(scaleAnimationListener); AnimatorSet animSet = new AnimatorSet(); animSet.playSequentially(animScale1); animSet.start(); }/ mData=date+"-"+mCManager.obtainDPInfo(centerYear, centerMonth)[i][j].strF; selectI=i; selectJ=j; //Log.e("---","--------农历:"+mCManager.obtainDPInfo(centerYear, centerMonth)[i][j].strF); isTextSelecterColor=true;
cirApr.put(date, circle);
invalidate();
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
invalidate();
if (null != onDatePickedListener) {
onDatePickedListener.onDatePicked(date);
}
}
} else if (mDPMode == DPMode.MULTIPLE) {
if (regions.contains(region)) {
regions.remove(region);
} else {
regions.add(region);
}
final String date = centerYear + "-" + centerMonth + "-" +
mCManager.obtainDPInfo(centerYear, centerMonth)[i][j].strG;
if (dateSelected.contains(date)) {
dateSelected.remove(date);
BGCircle circle = cirApr.get(date);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
ValueAnimator animScale = ObjectAnimator.ofInt(circle, "radius", circleRadius, 0);
animScale.setDuration(250);
animScale.setInterpolator(accelerateInterpolator);
animScale.addUpdateListener(scaleAnimationListener);
animScale.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
cirDpr.remove(date);
}
});
animScale.start();
cirDpr.put(date, circle);
}
cirApr.remove(date);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
invalidate();
}
} else {
dateSelected.add(date);
BGCircle circle = createCircle(
region.getBounds().centerX() + indexMonth * width,
region.getBounds().centerY() + indexYear * height);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
ValueAnimator animScale1 =
ObjectAnimator.ofInt(circle, "radius", 0, animZoomOut1);
animScale1.setDuration(250);
animScale1.setInterpolator(decelerateInterpolator);
animScale1.addUpdateListener(scaleAnimationListener);
ValueAnimator animScale2 =
ObjectAnimator.ofInt(circle, "radius", animZoomOut1, animZoomIn1);
animScale2.setDuration(100);
animScale2.setInterpolator(accelerateInterpolator);
animScale2.addUpdateListener(scaleAnimationListener);
ValueAnimator animScale3 =
ObjectAnimator.ofInt(circle, "radius", animZoomIn1, animZoomOut2);
animScale3.setDuration(150);
animScale3.setInterpolator(decelerateInterpolator);
animScale3.addUpdateListener(scaleAnimationListener);
ValueAnimator animScale4 =
ObjectAnimator.ofInt(circle, "radius", animZoomOut2, circleRadius);
animScale4.setDuration(50);
animScale4.setInterpolator(accelerateInterpolator);
animScale4.addUpdateListener(scaleAnimationListener);
AnimatorSet animSet = new AnimatorSet();
animSet.playSequentially(animScale1, animScale2, animScale3, animScale4);
animSet.start();
}
cirApr.put(date, circle);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
invalidate();
}
}
} else if (mDPMode == DPMode.NONE) {
if (regions.contains(region)) {
regions.remove(region);
} else {
regions.add(region);
}
final String date = centerYear + "-" + centerMonth + "-" +
mCManager.obtainDPInfo(centerYear, centerMonth)[i][j].strG;
if (dateSelected.contains(date)) {
dateSelected.remove(date);
} else {
dateSelected.add(date);
}
}
}
} } }
private void computeDate() { rightYear = leftYear = centerYear; topYear = centerYear - 1; bottomYear = centerYear + 1;
topMonth = centerMonth;
bottomMonth = centerMonth;
rightMonth = centerMonth + 1;
leftMonth = centerMonth - 1;
if (centerMonth == 12) {
rightYear++;
rightMonth = 1;
}
if (centerMonth == 1) {
leftYear--;
leftMonth = 12;
}
if (null != onDateChangeListener) {
onDateChangeListener.onYearChange(centerYear);
onDateChangeListener.onMonthChange(centerMonth);
}
}
interface OnDateChangeListener { void onMonthChange(int month);
void onYearChange(int year);
}
private enum SlideMode { VER,//垂直 HOR//横向 }
private class BGCircle { private float x, y; private int radius;
private ShapeDrawable shape;
public BGCircle(ShapeDrawable shape) {
this.shape = shape;
}
public float getX() {
return x;
}
public void setX(float x) {
this.x = x;
}
public float getY() {
return y;
}
public void setY(float y) {
this.y = y;
}
public int getRadius() {
return radius;
}
public void setRadius(int radius) {
this.radius = radius;
}
public ShapeDrawable getShape() {
return shape;
}
public void setShape(ShapeDrawable shape) {
this.shape = shape;
}
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB) private class ScaleAnimationListener implements ValueAnimator.AnimatorUpdateListener { @Override public void onAnimationUpdate(ValueAnimator animation) { MonthView.this.invalidate(); } }
}
找到地方加了?