过完年,到现在也没有认真的写代码,正好公司有需求,花了一个下午,写了一个尺子效果的自定义View,效果还行,但是还有很多需要改进的地方,希望大家指正!!!可以左右滑动,下面是关键代码!!
package com.example.drawrulerview;
import OnCustomRurleListener.OnCustomViewListener;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.graphics.Paint.FontMetricsInt;
import android.graphics.PorterDuff.Mode;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.Toolbar;
@SuppressLint("NewApi")
public class CustomRuleView extends View {
private final int NUM = 4;// 整个屏幕宽度内要显示的几个条数
private Canvas mCanvas;
private Paint mPaint;
private int mViewWidth;
private int mViewHeight;
private String middleStrTime;
private double millsWidthPrecent;// 每一秒要代表的长度
private double timePrecent;// 每一份长度要代表的时间(s)
private float xStar, xEnd;
public CustomRuleView(Context context, AttributeSet attrs) {
super(context, attrs);
initFirstData();
}
private void initFirstData() {
// TODO Auto-generated method stub
this.middleStrTime = Utils.timeLong2Date(System.currentTimeMillis());
}
private void initData() {
if (mPaint == null) {
mPaint = new Paint();
mViewHeight = this.getHeight();
mViewWidth = this.getWidth();
millsWidthPrecent = mViewWidth / (NUM * 60 * 60 * 1.0);
timePrecent = NUM * 60 * 60 * 1.0 / mViewWidth;
Log.d("msg", "---prcetn:" + millsWidthPrecent);
}
}
@Override
protected void onDraw(Canvas canvas) {
clear(canvas);
initData();
drawView(canvas);
super.onDraw(canvas);
}
private void drawView(Canvas mCanvas) {
this.mCanvas = mCanvas;
drawMiddleLine();
drawTextTopMiddle(middleStrTime);
drawRuleDeg();
}
/**
* 清除界面
*
* @param mCanvas
*/
public void clear(Canvas mCanvas) {
Paint paint = new Paint();
paint.setXfermode(new PorterDuffXfermode(Mode.DST));
mCanvas.drawPaint(paint);
}
/*
* 根据中间的刻度,画出其他刻度
*/
private void drawRuleDeg() {
mPaint.setColor(Color.GRAY);
mPaint.setTextSize(mViewHeight / 6);
EntityConversionTime conversionTime = Utils
.getCurrentTimeEntity(middleStrTime);
// 距离下一个整点的时间(单位s)
int nxteMissTmp = (60 - conversionTime.getMinNUM() - 1) * 60 + 60
- conversionTime.getMillNUM();
// 距离上一个整点的时间(单位s)
int beforeMissTmp = conversionTime.getMinNUM() * 60
+ conversionTime.getMillNUM();
Log.d("msg", "---width:" + nxteMissTmp * millsWidthPrecent
+ " precent:" + millsWidthPrecent + " realWidth:"
+ mViewWidth);
drawLineText((float) (mViewWidth / 2 + (nxteMissTmp)
* millsWidthPrecent), conversionTime.getHourNUM() + 1);
drawLineText((float) (mViewWidth / 2 + (nxteMissTmp + 3600)
* millsWidthPrecent), conversionTime.getHourNUM() + 2);
// 左边
drawLineText((float) (mViewWidth / 2 - beforeMissTmp
* millsWidthPrecent), conversionTime.getHourNUM());
drawLineText((float) (mViewWidth / 2 - (beforeMissTmp + 3600)// 多一个周期
* millsWidthPrecent), conversionTime.getHourNUM() - 1);
}
private void drawLineText(float left, int TvTime) {
RectF rectF = new RectF(left - 20, mViewHeight / 3, left + 20,
mViewHeight / 2);
drawCeninView(rectF, mCanvas, mPaint, TvTime + ":00");
mCanvas.drawLine(left, mViewHeight*2 / 3 -10, left, mViewHeight*2 / 3 ,
mPaint);
}
private void drawTextTopMiddle(String tvStr) {
this.middleStrTime = tvStr;
mPaint.setColor(Color.WHITE);
mPaint.setTextSize(mViewHeight / 4);
RectF rectF = new RectF(0, 0, mViewWidth, mViewHeight / 3);
drawCeninView(rectF, mCanvas, mPaint, tvStr);
}
/**
* 在矩形的中间绘制
*
* @param targetRect0
* @param canvas
* @param paint
* @param tvStr
*/
private void drawCeninView(RectF targetRect0, Canvas canvas, Paint paint,
String tvStr) {
FontMetricsInt fontMetrics = paint.getFontMetricsInt();
int baseline = (int) (targetRect0.top
+ (targetRect0.bottom - targetRect0.top - fontMetrics.bottom + fontMetrics.top)
/ 2 - fontMetrics.top);
paint.setTextAlign(Paint.Align.CENTER);
canvas.drawText(tvStr, targetRect0.centerX(), baseline, paint);
}
/**
* 绘制中间的线
*/
private void drawMiddleLine() {
// TODO Auto-generated method stub
mPaint.setColor(Color.YELLOW);
mPaint.setStrokeWidth(2);
mCanvas.drawLine(mViewWidth / 2, 0, mViewWidth / 2, mViewHeight, mPaint);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.d("msg", "touching1");
xStar = event.getX();
break;
case MotionEvent.ACTION_UP:
Log.d("msg", "touching2");
xEnd = 0;
xStar = 0;
break;
case MotionEvent.ACTION_MOVE:
xEnd = event.getX();
drawViewTouch(xStar - xEnd);
xStar = event.getX();
break;
default:
break;
}
return super.onTouchEvent(event);
}
/**
* 滑动的时候调用的方法
*
* @param f
*/
private void drawViewTouch(float f) {
Log.d("msg", "touching3:---->" + f);
if (f != 0) {// 滑动调用相关的方法
long time = (long) (Utils.date2TimeLong(middleStrTime) + timePrecent
* f * 1000);
middleStrTime = Utils.timeLong2Date(time);
}
Log.v("msg", "middleTime:" + middleStrTime);
invalidate();
}
}
package com.example.drawrulerview;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.TimeZone;
public class Utils {
/**
* 1393445856--->2014-05-01 00:01:58
*
* @param time
* @return
*/
public static String timeLong2Date(long time) {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return formatter.format(time);
}
/**
* 2014-05-01 00:01:58 --->1393445565
* @param time
* @return
*/
public static long date2TimeLong(String time) {
Calendar c = Calendar.getInstance();
try {
c.setTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(time));
} catch (ParseException e) {
e.printStackTrace();
}
return c.getTimeInMillis();
}
/**
* 获取当前日期的实体
*
* @return
*/
public static EntityConversionTime getCurrentTimeEntity(String strTime) {
final Calendar c = Calendar.getInstance();
c.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));
try {
c.setTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(strTime));
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
EntityConversionTime entityConversionTime = new EntityConversionTime();
entityConversionTime.setYearNUM(c.get(Calendar.YEAR));// 获取当前年份
entityConversionTime.setMonthNUM(c.get(Calendar.MONTH) + 1);// 获取当前月份
entityConversionTime.setDayNUM(c.get(Calendar.DAY_OF_MONTH));// 获取当前月份的日期号码
String mWay = String.valueOf(c.get(Calendar.DAY_OF_WEEK));
entityConversionTime.setHourNUM(c.get(Calendar.HOUR_OF_DAY));
entityConversionTime.setMinNUM(c.get(Calendar.MINUTE));
entityConversionTime.setMillNUM(c.get(Calendar.SECOND));
int tmp = 1;
if ("1".equals(mWay)) {
tmp = 7;
} else if ("2".equals(mWay)) {
tmp = 1;
} else if ("3".equals(mWay)) {
tmp = 2;
} else if ("4".equals(mWay)) {
tmp = 3;
} else if ("5".equals(mWay)) {
tmp = 4;
} else if ("6".equals(mWay)) {
tmp = 5;
} else if ("7".equals(mWay)) {
tmp = 6;
}
entityConversionTime.setWeekNUM(tmp);
tmp = entityConversionTime.getMonthNUM();
if (tmp == 1 || tmp == 3 || tmp == 5 || tmp == 7 || tmp == 8
|| tmp == 10 || tmp == 12) {// 31天
tmp = 31;
} else if (tmp == 2) {
if (isLeapYear(entityConversionTime)) {
tmp = 28;
} else {
tmp = 27;
}
} else {
tmp = 30;
}
entityConversionTime.setMonthAllday(tmp);
// 设置季度
if (entityConversionTime.getMonthNUM() <= 3) {
entityConversionTime.setFest(1);
} else if (entityConversionTime.getMonthNUM() <= 6) {
entityConversionTime.setFest(2);
} else if (entityConversionTime.getMonthNUM() <= 9) {
entityConversionTime.setFest(3);
} else if (entityConversionTime.getMonthNUM() <= 12) {
entityConversionTime.setFest(4);
}
// + entityConversionTime.getMonthAllday() + " "
// + entityConversionTime.getMonthNUM() + " "
// + entityConversionTime.getWeekNUM() + " "
// + entityConversionTime.getYearNUM() + " ");
return entityConversionTime;
}
/**
* 判断是否为闰年 false = not leap
*/
private static boolean isLeapYear(EntityConversionTime conversionTime) {
boolean ret;
if (conversionTime.getYearNUM() / 4 == 0
&& conversionTime.getYearNUM() / 100 != 0) {//
ret = true;
} else {
ret = false;
}
return ret;
}
}
记录几个问题:1.
yyyy-MM-dd HH:mm:ss 其中HH 表示24小时制 hh表示12小时制