Android 自定义雷达图

package com.cnten.demo.graph;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Paint.FontMetrics;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.Region;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;

/**
 * 雷达图
 * 
 * @author Administrator
 * 
 */
public class LifeWheelRadarGraph extends View {
	private static int count = 8;
	private float angle = 360 / count;
	private int point_radius = 5; // 画点的半径
	private int regionwidth = 40; // 选择分值小区域宽度
	private int valueRulingCount = 5; // 画等分值线
	private int radius;
	private int centerX;
	private int centerY;
	private static String[] titles = { "工作", "财富", "健康", "娱乐", "家庭", "社交",
			"精神", "贡献" };
	private static LifeWheelRadarGraph lfrg = null;
	private Point[] pts; // 维度端点
	private Region[] regions; // 打分点区域
	private float[] regionValues; // 打分点分数
	private Path valuePath;
	private static float[] values = { 8, 6, 8, 6, 6, 6, 4, 5 }; // 各维度分值
	private int maxValue = 10;
	private Point[] value_pts; // 维度端点
	private Paint paint;
	private Paint valuePaint;

	public float[] getValues() {
		return values;
	}

	public static LifeWheelRadarGraph getInstance(Context context,
			String[] titile, float[] values) {
		titles = titile;
		LifeWheelRadarGraph.values = values;
		count = titile.length;
		if (lfrg == null)
			lfrg = new LifeWheelRadarGraph(context);
		return lfrg;
	}

	public static LifeWheelRadarGraph newInstance(Context context,
			String[] titile, float[] values) {
		titles = titile;
		LifeWheelRadarGraph.values = values;
		count = titile.length;
		return new LifeWheelRadarGraph(context);
	}

	private LifeWheelRadarGraph(Context context) {
		super(context);
		init();
	}

	/**
	 * 初始化方法
	 */
	public void init() {
		paint = new Paint();
		valuePaint = new Paint();
		pts = new Point[count];
		value_pts = new Point[count];
		valuePath = new Path();
		for (int i = 0; i < count; i++) {
			pts[i] = new Point();
			value_pts[i] = new Point();
		}
		regionValues = new float[count * valueRulingCount * 2];
		regions = new Region[count * valueRulingCount * 2];
		for (int i = 0; i < regions.length; i++) {
			regions[i] = new Region();
		}
	}

	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		radius = Math.min(h, w) / 2 - 40;
		centerX = w / 2;
		centerY = h / 2;

		for (int i = 0; i < count; i++) {
			pts[i].x = centerX
					+ (int) (radius * Math.cos(Math.toRadians(angle * i)));
			pts[i].y = centerY
					- (int) (radius * Math.sin(Math.toRadians(angle * i)));

			for (int j = 1; j <= valueRulingCount * 2; j++) {
				int x = centerX + (pts[i].x - centerX) / (valueRulingCount * 2)
						* j;
				int y = centerY + (pts[i].y - centerY) / (valueRulingCount * 2)
						* j;
				regions[i * valueRulingCount * 2 + j - 1].set(x - regionwidth
						/ 2, y - regionwidth / 2, x + regionwidth / 2, y
						+ regionwidth / 2);
				regionValues[i * valueRulingCount * 2 + j - 1] = j;
			}
		}
		postInvalidate();
		super.onSizeChanged(w, h, oldw, oldh);
	}

	@SuppressWarnings("unused")
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		int action = event.getAction();
		float x = event.getX();
		float y = event.getY();

		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			for (int i = 0; i < regions.length; i++) {
				if (regions[i].contains((int) x, (int) y)) {
					values[(int) (i / (valueRulingCount * 2))] = regionValues[i];
					break;
				}
			}
			invalidate();
			break;
		case MotionEvent.ACTION_MOVE:

			break;
		case MotionEvent.ACTION_UP:

			break;
		}
		return super.onTouchEvent(event);
	}

	@Override
	public boolean onKeyLongPress(int keyCode, KeyEvent event) {
		// TODO Auto-generated method stub
		return super.onKeyLongPress(keyCode, event);
	}

	@Override
	protected void onDraw(Canvas canvas) {
		canvas.drawColor(Color.WHITE);/* 设置画布的颜色 */
		paint.setAntiAlias(true);
		paint.setColor(Color.GRAY); // 画边框线
		paint.setStyle(Paint.Style.FILL_AND_STROKE);
		for (int i = 0; i < count; i++) {
			int end = i + 1 == count ? 0 : i + 1;

			for (int j = 1; j <= valueRulingCount; j++) {
				canvas.drawLine(centerX + (pts[i].x - centerX) / 5 * j, centerY
						+ (pts[i].y - centerY) / 5 * j, centerX
						+ (pts[end].x - centerX) / 5 * j, centerY
						+ (pts[end].y - centerY) / 5 * j, paint);
			}

			canvas.drawLine(centerX, centerY, pts[i].x, pts[i].y, paint);
		}

		// 写文字
		paint.setTextSize(20);
		paint.setColor(Color.BLACK);
		FontMetrics fontMetrics = paint.getFontMetrics();
		float fontHegiht = -fontMetrics.ascent;
		for (int i = 0; i < count; i++) {
			if ((angle * i == 90.0) || (angle * i == 270.0))
				paint.setTextAlign(Align.CENTER);
			else if ((angle * i < 90) || (angle * i > 270))
				paint.setTextAlign(Align.LEFT);
			else if ((angle * i > 90) || (angle * i < 270))
				paint.setTextAlign(Align.RIGHT);

			if (angle * i == 270.0)
				canvas.drawText(titles[i], pts[i].x, pts[i].y + fontHegiht,
						paint);
			else
				canvas.drawText(titles[i], pts[i].x, pts[i].y, paint);
		}

		// 画方向盘分值区域
		for (int i = 0; i < count; i++) {
			value_pts[i].x = (int) (centerX + (pts[i].x - centerX) * values[i]
					/ maxValue);
			value_pts[i].y = (int) (centerY + (pts[i].y - centerY) * values[i]
					/ maxValue);
		}

		valuePath.reset();
		valuePaint.setAntiAlias(true);
		valuePaint.setColor(Color.BLUE);
		valuePaint.setStyle(Paint.Style.FILL_AND_STROKE);
		for (int i = 0; i < pts.length; i++) {
			// 给valuePath赋值
			if (i == 0)
				valuePath.moveTo(value_pts[i].x, value_pts[i].y);
			else
				valuePath.lineTo(value_pts[i].x, value_pts[i].y);
			// 画取分圆圈
			canvas.drawCircle(value_pts[i].x, value_pts[i].y, point_radius,
					paint);
		}
		valuePaint.setAlpha(150);
		canvas.drawPath(valuePath, valuePaint);
	}
}

使用方法:

package com.cnten.demo;

import com.cnten.demo.graph.LifeWheelRadarGraph;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.Toast;

public class SendActivity extends Activity {

	private String[] titles = { "工作", "财富", "健康", "娱乐", "家庭", "社交", "精神", "贡献",
			"1111", "21312" };
	private float[] values = { 8, 6, 8, 6, 6, 6, 4, 5, 2, 3 }; // 各维度分值

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_send);

		LifeWheelRadarGraph lf = LifeWheelRadarGraph.newInstance(this, titles,
				values);
		addContentView(lf, new LayoutParams(LayoutParams.WRAP_CONTENT,
				LayoutParams.WRAP_CONTENT));

	}
}
源码地址: 点击打开链接   访问密码 d7ca

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值