您的位置:首页 > 移动开发 > Android开发

从0开始在Android下开发生活方向盘应用(自绘雷达图)

2012-06-12 15:23 351 查看
30天敏捷生活(1):意识你的生活方向盘敏捷个人:你有自己的生活方向盘吗?中提到生活方向盘是敏捷个人的一个重要工具,之前发不过图片和Excel格式的方向盘工具。



但现在是移动时代,所以利用空闲时间也编写了一个Android应用,效果图如下。这是我在Android下开发的第一个应用,所以本篇将介绍一下如何从0开始在Android开发这个应用。



下载SDK http://developer.android.com/sdk/index.html

我是在windows下开发,所以下载了installer_r18-windows.exe



安装SDK

运行上一步下载的installer_r18-windows.exe,然后运行SDK Manager下载你需要版本的SDK。2.3的是常用的 ,我手机是2.2的,所以我还下载了一个2.2版本的。





安装ADT Plugin for Eclipse

https://dl-ssl.google.com/android/eclipse/下载,具体如何使用Eclipse这里就不说了


以上把开发环境都准备好了,现在开始新建一个项目,取名AgileMe。Android的基本概念和常识这里也不介绍了,大家网上可以找到很多。在开始之前,简单介绍一下方向盘应用的需求。

需求

方向盘分为8个维度,每个维度采用10分制打分,每个维度的分值区域是我们生活的饱满度。程序初始化后,我们可以通过直接在各维度点击来设定维度的分值,系统自动重绘方向盘图形。当然,支持数据保存是必要地:)

思路

之前找过有没有直接的雷达图控件,发现还没有发现好用的。因为绘制这个图也简单,所以干脆自己操刀从头开始。这个图元也少,所以可以不必像工作中那样关注性能。

绘制静态的雷达格线

绘制文字:这里需要按照角度来设定文字的对齐方式,否则左边的文字可能就要压线了

绘制分值点

对分值区域进行着色绘制

为了能够响应点击操作,对每一个分值刻度周围都条件一个小矩形Region,这样可以响应onTouch事件来判断打几分

代码也不复杂,主要就是根据想绘制的点进行计算,然后再drawText、drawLine等参数中传递正确即可。数据上主要是通过设定了很多对应的数组(维度点、刻度值、区域等)。具体代码如下:

public class LifeWheelRadarGraph extends View {
private 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 String[] titles = {"工作","财富","健康","娱乐","家庭","社交","精神","贡献"};

private Point[] pts;  //维度端点
private Region[] regions;       //打分点区域
private float[] regionValues;   //打分点分数
private Path valuePath;
private 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 void setValues(float[] values) {
Assert.assertTrue("传递的values数组大小不是"+count, values.length == count);
this.values = values;
}

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

private 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();
}

}

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

public LifeWheelRadarGraph(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}

@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);
}

@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);
}
}


保存方向盘分值

最后我们还要保存分值,这里使用了简单的SharedPreferences

public class AgileMeActivity extends Activity {
private LifeWheelRadarGraph graph = null;
private SharedPreferences settings;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
graph = (LifeWheelRadarGraph)findViewById(R.id.lifeWheelRadarGraph1);
// Restore preferences
settings = getSharedPreferences("LifeWheel", 0);
String valueStr = settings.getString("values", "8,6,8,6,6,6,4,5");
try {
String[] valuesStr = valueStr.split(",");
float[] values = new float[valuesStr.length];
for(int i = 0; i <valuesStr.length; i++)
values[i] = Float.parseFloat(valuesStr[i]);

graph.setValues(values);
} catch (Exception e) {
}
}

protected void onStop(){
super.onStop();
SharedPreferences.Editor editor = settings.edit();
float[] values = graph.getValues();
String valueStr= "";
for(int i=0; i <values.length; i++)
valueStr =  valueStr + "," + values[i];
valueStr = valueStr.substring(1);
editor.putString("values", valueStr);
editor.commit();
}
}


应用下载

#敏捷个人# 生活方向盘#工具#Android应用提供下载 通过@微盘 分享文件"AgileMe.apk" http://t.cn/zWvgPgO

[b]推荐:你可能需要的在线电子书[/b]

[b]我的微博:http://weibo.com/openexpressapp[/b]

敏捷个人sina围裙:http://q.t.sina.com.cn/135484

欢迎转载,转载请注明:转载自敏捷个人网站
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: