标签:
效果图:

实现源码:
/**
* FunctionCurveView.java
* @author Lanfog
* @datetime a01b-6-ab下午b:38:01
*/
package me.lanfog.myandroid.widget;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
/**
* 函数曲线图
*/
public class CurveView extends View {
private Paint mPaint;
private CurveUnit mCurveUnit = new CurveUnit() {
@Override
public int getCenterY() {
// TODO Auto-generated method stub
return getHeight()/2;
}
@Override
public int getCenterX() {
// TODO Auto-generated method stub
return getWidth()/2;
}
@Override
public float function(float x) {
// TODO Auto-generated method stub
return (float) Math.sin(x);
}
};
public CurveView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
// TODO Auto-generated constructor stub
init();
}
public CurveView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
init();
}
public CurveView(Context context) {
super(context);
// TODO Auto-generated constructor stub
init();
}
private void init(){
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setStyle(Paint.Style.STROKE);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int measuredWidth = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
int measuredHeight = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
setMeasuredDimension(measuredWidth, measuredHeight);
}
@Override
protected void onDraw(Canvas canvas) {
int w = getWidth(); // 控件宽度
int h = getHeight(); // 控件高度
int p = mCurveUnit.getPadding(); // 控件内部填充
int cx = mCurveUnit.getCenterX(); // 中心横坐标
int cy = mCurveUnit.getCenterY(); // 中心纵坐标
mPaint.setStrokeWidth(2);
canvas.drawLine(p, cy, w - p, cy, mPaint);
canvas.drawLine(cx, p, cx, h - p, mPaint);
float pr = mCurveUnit.getPrecision(); // 刻度精度
float sp = mCurveUnit.getSpacing(); // 刻度间隔
float x, y;
mPaint.setStrokeWidth(1);
mPaint.setTextSize(12);
int a = 3; // 短线刻度长度
int b = 8; // 长线刻度长度
// 中
canvas.drawText("0", cx + 15, cy + 15, mPaint);
// 左
for(int i=-1;;i--){
x = cx + i * sp;
if(x < p) break;
if(i % 5 == 0){ // 每5个刻度绘制一个数字
canvas.drawLine(x, cy, x, cy - b, mPaint);
canvas.drawText("" + i * pr, x, cy + 15, mPaint);
}else
canvas.drawLine(x, cy, x, cy - a, mPaint);
}
// 上
for(int i=1;;i++){
y = cy - i * sp;
if(y < p) break;
if(i % 5 == 0){
canvas.drawLine(cx, y, cx + b, y, mPaint);
canvas.drawText("" + i * pr, cx + 10, y, mPaint);
}else
canvas.drawLine(cx, y, cx + a, y, mPaint);
}
// 右
for(int i=1;;i++){
x = cx + i * sp;
if(x > w - p) break;
if(i % 5 == 0){
canvas.drawLine(x, cy, x, cy - b, mPaint);
canvas.drawText("" + i * pr, x, cy - 10, mPaint);
}else
canvas.drawLine(x, cy, x, cy - a, mPaint);
}
// 下
for(int i=-1;;i--){
y = cy - i * sp;
if(y > h - p) break;
if(i % 5 == 0){
canvas.drawLine(cx, y, cx + b, y, mPaint);
canvas.drawText("" + i * pr, cx + 10, y, mPaint);
}else
canvas.drawLine(cx, y, cx + a, y, mPaint);
}
mPaint.setColor(Color.RED);
boolean s = false; // 是否为起始点
float tx, ty; // 临时保存坐标点
float lx = 0f, ly = 0f; // 上一次保存坐标点
// 负
for(int i=0;;i--){
if(cx + i * sp < p) break;
tx = x = i * pr;
ty = y = mCurveUnit.function(x);
x = cx + i * sp;
y = cy - y / pr * sp;
if(i % 10 == 0) // 每10个刻度绘制一个(x,y)值
canvas.drawText("(" + String.format("%.2f", tx) + "," + String.format("%.2f", ty) + ")", x, y, mPaint);
if(s)
canvas.drawLine(lx, ly, x, y, mPaint);
else
s = true;
lx = x;
ly = y;
}
s = false;
// 正
for(int i=0;;i++){
if(cx + i * sp > w - p) break;
tx = x = i * pr;
ty = y = mCurveUnit.function(x);
x = cx + i * sp;
y = cy - y / pr * sp;
if(i % 10 == 0)
canvas.drawText("(" + String.format("%.2f", tx) + "," + String.format("%.2f", ty) + ")", x, y, mPaint);
if(s)
canvas.drawLine(lx, ly, x, y, mPaint);
else
s = true;
lx = x;
ly = y;
}
}
public static abstract class CurveUnit {
/**
* 函数实现
*/
public abstract float function(float x);
/**
* 获取中心的水平位置
*/
public abstract int getCenterX();
/**
* 获取中心的垂直位置
*/
public abstract int getCenterY();
/**
* 获取刻度精度
*/
public float getPrecision(){
return 0.2f;
}
/**
* 获取刻度间隔
*/
public float getSpacing(){
return 10f;
}
/**
* 获取内部填充
*/
public int getPadding(){
return 5;
}
}
public CurveUnit getCurveUnit() {
return mCurveUnit;
}
public void setCurveUnit(CurveUnit mCurveUnit) {
this.mCurveUnit = mCurveUnit;
}
}
标签:
原文地址:http://my.oschina.net/lanfog/blog/470992