当前位置:   article > 正文

android 动态图形,Android 绘制动态图

原生android 动态绘制图片

最近准备技能大赛,需要将从传感器中读出的数据在移动客户端以图的形式绘制出来,因为平时很少绘图,于是各种查资料,算是勉强做出来了。

以下是大赛理论效果图(左)和实际效果图(右),真的是理想很丰满,现实很骨感啊!

e95fc5bf6cb2666361f5697d3e4d2650.png    

a121e8dd7ae26d81fe6f2d56eb7e038e.png

制作的整体思路:

创建一个继承与View类自定义类

自定义类覆盖其中的onDraw()方法

在MainActivity中invalidate()方法来调用onDraw()方法来进行图形的重绘.

绘制一个基本表:

(注意:代码中使用了变量)

1、绘制矩形

Paint paint = newPaint();

paint.setColor(Color.BLACK);

paint.setStyle(Paint.Style.STROKE);

Rect chartRec= new Rect(OFFSET_LEFT, OFFSET_TOP, CHARTW +OFFSET_LEFT,

CHARTH+OFFSET_TOP);

canvas.drawRect(chartRec, paint);

2、绘制左侧数值标记

fcecaa27ea5212ceb9bf034c36bfbf34.gifcanvas.drawText("100", OFFSET_LEFT - TEXT_OFFSET - 15, OFFSET_TOP + 5,

paint);for (int i = 9; i > 0; i--) {

canvas.drawText("" + 10 * (10 - i), OFFSET_LEFT - TEXT_OFFSET - 15,

OFFSET_TOP+ CHARTH / 10 *i, paint);

}

canvas.drawText("0", OFFSET_LEFT - TEXT_OFFSET - 10, OFFSET_TOP+ CHARTH, paint);

fcecaa27ea5212ceb9bf034c36bfbf34.gif

3、绘制虚线

DashPathEffect是PathEffect类的一个子类,可以使paint画出类似虚线的样子,并且可以任意指定虚实的排列方式。

代码中的float数组,必须是偶数长度,且>=2,指定了多少长度的实线之后再画多少长度的空白.

如本代码中,绘制长度2的实线,再绘制长度2的空白,再绘制长度2的实线,再绘制长度2的空白,依次重复.1是偏移量

PathEffect effects = new DashPathEffect(new float[] { 2, 2, 2, 2 }, 1);

这样一个基本的表格绘制完成。

动态改变界面的方法:

fcecaa27ea5212ceb9bf034c36bfbf34.gifHandler handler=newHandler();

Runnable runnable=newRunnable(){

@Overridepublic voidrun() {//TODO Auto-generated method stub//要做的事情

handler.postDelayed(this, 1000);

}

};

fcecaa27ea5212ceb9bf034c36bfbf34.gif

在这里我们采用消息传递机制中Handler的postDelayed(Runnable, long)

方法做定时器,每隔一秒钟发送一次Runnable对象(该对象最后将会被封装成Message对象)执行一次子线程中的操作。

最后,贴上所有代码:

main.xml

fcecaa27ea5212ceb9bf034c36bfbf34.gif<?xml version="1.0" encoding="utf-8"?>

fcecaa27ea5212ceb9bf034c36bfbf34.gif

MainActivity.class

fcecaa27ea5212ceb9bf034c36bfbf34.gifpublic class MainActivity extendsActivity {privateHandler handler;privateDrawTest dtest;

@Overrideprotected voidonCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);

setContentView(R.layout.main);

init();

}private voidinit() {

LinearLayout layout=(LinearLayout) findViewById(R.id.root);

dtest= new DrawTest(this);

dtest.invalidate();

layout.addView(dtest);

handler= newHandler();

handler.post(newRunnable() {

@Overridepublic voidrun() {

dtest.invalidate();

handler.postDelayed(this, 2000);

}

});

}}

fcecaa27ea5212ceb9bf034c36bfbf34.gif

DrawTest.class

fcecaa27ea5212ceb9bf034c36bfbf34.gifpublic class DrawTest extendsView {private int CHARTH = 600;//表格的高

private int CHARTW = 400;//表格的宽

private int OFFSET_LEFT = 70;//距离左边界距离

private int OFFSET_TOP = 80;//距离右边界距离

private int TEXT_OFFSET = 20;//文本距离设置

private int X_INTERVAL = 20;//X坐标间隔距离

private List plist;//点集合

publicDrawTest(Context context) {super(context);

plist= new ArrayList();

}

@Overrideprotected voidonDraw(Canvas canvas) {super.onDraw(canvas);

drawTable(canvas);

preparePoint();

drawPoint(canvas);

}/*** 绘制表

*@paramcanvas*/

private voiddrawTable(Canvas canvas) {

Paint paint= newPaint();

paint.setColor(Color.BLACK);

paint.setStyle(Paint.Style.STROKE);

Rect chartRec= new Rect(OFFSET_LEFT, OFFSET_TOP, CHARTW +OFFSET_LEFT,

CHARTH+OFFSET_TOP);

canvas.drawRect(chartRec, paint);

Path textPath= new Path();//选择一块区域,准备写文字“曲线图测试”

paint.setStyle(Paint.Style.FILL);

textPath.moveTo(200, 30);//区域开始

textPath.lineTo(400, 30);//区域结束

paint.setTextSize(20);

paint.setAntiAlias(true);//指定是否使用抗锯齿功能,会消耗较大资源,绘制图形速度会变慢。

canvas.drawTextOnPath("曲线图测试", textPath, 0, 0, paint);//左侧数值标记

canvas.drawText("100", OFFSET_LEFT - TEXT_OFFSET - 15, OFFSET_TOP + 5,

paint);for (int i = 9; i > 0; i--) {

canvas.drawText("" + 10 * (10 - i), OFFSET_LEFT - TEXT_OFFSET - 15,

OFFSET_TOP+ CHARTH / 10 *i, paint);

}

canvas.drawText("0", OFFSET_LEFT - TEXT_OFFSET - 10, OFFSET_TOP+CHARTH, paint);//绘制虚线

Path path = newPath();/*** PathEffect是用来控制绘制轮廓(线条)的方式。

* DashPathEffect是PathEffect类的一个子类,可以使paint画出类似虚线的样子,并且可以任意指定虚实的排列方式.

* 代码中的float数组,必须是偶数长度,且>=2,指定了多少长度的实线之后再画多少长度的空白.

* 如本代码中,绘制长度2的实线,再绘制长度2的空白,再绘制长度2的实线,再绘制长度2的空白,依次重复.1是偏移量,*/PathEffect effects= new DashPathEffect(new float[] { 2, 2, 2, 2 }, 1);

paint.setStyle(Paint.Style.STROKE);

paint.setAntiAlias(false);

paint.setPathEffect(effects);//用于设置绘制路径时的路径效果,如点划线。

for (int i = 1; i < 10; i++) {

path.moveTo(OFFSET_LEFT, OFFSET_TOP+ CHARTH / 10 *i);

path.lineTo(OFFSET_LEFT+ CHARTW, OFFSET_TOP + CHARTH / 10 *i);

canvas.drawPath(path, paint);

}

}/*** 准备绘制点*/

private voidpreparePoint() {//设置点的Y坐标为30-40

int py = (CHARTH/10)*6+OFFSET_TOP + (int) Math.rint((Math.random() * (CHARTH/10)));

Point p= new Point(OFFSET_LEFT +CHARTW, py);if (plist.size() > 21) {

plist.remove(0);//控制点的个数//改变每一个点的X坐标

for (int i = 0; i < 20; i++) {if (i == 0)

plist.get(i).x-= (X_INTERVAL - 2);elseplist.get(i).x-=X_INTERVAL;

}

plist.add(p);

}else{for (int i = 0; i < plist.size() - 1; i++) {

plist.get(i).x-=X_INTERVAL;

}

plist.add(p);

}

}/*** 绘制点

*

*@paramcanvas*/

private voiddrawPoint(Canvas canvas) {

Paint paint= newPaint();

paint.setColor(Color.BLACK);

paint.setStrokeWidth(3);//设置笔触的宽度

if (plist.size() >= 2) {for (int i = 0; i < plist.size() - 1; i++) {

canvas.drawPoint(plist.get(i).x, plist.get(i).y, paint);

}

}

}

}

fcecaa27ea5212ceb9bf034c36bfbf34.gif

【注:invalidate

()和postInvalidate()方法的选择:文档中已经写的很清楚了,如果要使用invalidate()必须要在UI主线程当中,如果不在UI主线程中,就要去调用postInValidate()】

如果大家有什么更好的方法或该文中有什么不足,希望大家指点。

原文:http://www.cnblogs.com/scetopcsa/p/3765719.html

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/254591
推荐阅读
相关标签
  

闽ICP备14008679号