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

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

    

制作的整体思路:

  1. 创建一个继承与View类自定义类
  2. 自定义类覆盖其中的onDraw()方法
  3. 在MainActivity中invalidate()方法来调用onDraw()方法来进行图形的重绘.

绘制一个基本表:

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

1、绘制矩形

     Paint paint = new Paint();
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、绘制左侧数值标记

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

3、绘制虚线

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

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

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

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

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

动态改变界面的方法:

Handler handler=new Handler();
Runnable runnable=new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
//要做的事情
handler.postDelayed(this, 1000);
}
};

在这里我们采用消息传递机制中Handler的postDelayed(Runnable, long) 方法做定时器,每隔一秒钟发送一次Runnable对象(该对象最后将会被封装成Message对象)执行一次子线程中的操作。

最后,贴上所有代码:

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:id="@+id/root"
android:orientation = "vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
</LinearLayout> </LinearLayout>

MainActivity.class

public class MainActivity extends Activity {
private Handler handler;
private DrawTest dtest; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
init(); } private void init() {
LinearLayout layout = (LinearLayout) findViewById(R.id.root);
dtest = new DrawTest(this);
dtest.invalidate();
layout.addView(dtest);
handler = new Handler();
handler.post(new Runnable() { @Override
public void run() {
dtest.invalidate();
handler.postDelayed(this, 2000); }
});
} }

DrawTest.class

public class DrawTest extends View {
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<Point> plist;//点集合 public DrawTest(Context context) {
super(context);
plist = new ArrayList<Point>();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
drawTable(canvas);
preparePoint();
drawPoint(canvas);
}
/**
* 绘制表
* @param canvas
*/
private void drawTable(Canvas canvas) {
Paint paint = new Paint();
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 = new Path();
/**
* 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 void preparePoint() {
//设置点的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);
else
plist.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);
} }
/**
* 绘制点
*
* @param canvas
*/
private void drawPoint(Canvas canvas) { Paint paint = new Paint();
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);
}
}
}
}

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

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

Demo下载http://download.csdn.net/detail/af74776/7440807

Android 绘制动态图的更多相关文章

  1. python绘制动态图

    1.需要注意的问题 解决 MatplotlibDeprecationWarning: Using default event loop until function specific to this ...

  2. 4.14Python数据处理篇之Matplotlib系列(十四)---动态图的绘制

    目录 目录 前言 (一)需求分析 (二)随机数的动态图 1.思路分析: 2.源代码: 2.输出效果: 目录 前言 学习matplotlib已经到了尾声,没有必要再继续深究下去了,现今只是学了一些基础的 ...

  3. 转+更新 Graphviz 教程,例子+ 高级应用 写代码,编程绘制架构图(分层拓扑图) 转自官网

    1. Graphviz介绍 Graphviz是大名鼎鼎的贝尔实验室的几位牛人开发的一个画图工具. 它的理念和一般的“所见即所得”的画图工具不一样,是“所想即所得”. Graphviz提供了dot语言来 ...

  4. Android自定义控件 -Canvas绘制折线图(实现动态报表效果)

    有时候我们在项目中会遇到使用折线图等图形,Android的开源项目中为我们提供了很多插件,但是很多时候我们需要根据具体项目自定义这些图表,这一篇文章我们一起来看看如何在Android中使用Canvas ...

  5. [置顶] Android中使用Movie显示gif动态图

    转载请注明:  http://blog.csdn.net/u012975705/article/details/48717391 在看这篇博文之前对attr自定义属性还是不是很熟的童鞋可以先看看:An ...

  6. Android自己定义组件系列【9】——Canvas绘制折线图

    有时候我们在项目中会遇到使用折线图等图形,Android的开源项目中为我们提供了非常多插件,可是非常多时候我们须要依据详细项目自己定义这些图表,这一篇文章我们一起来看看怎样在Android中使用Can ...

  7. 【Android开源框架】使用andbase开发框架实现绘制折线图

    在Android中,当有绘制折线图的需求时.大多数人使用的AChartEngine,来进行折线图的绘制.AChartEngine图表引擎确实能够实现折线图的功能.除此之外,我们还能够使用andbase ...

  8. Android自定义组件系列【9】——Canvas绘制折线图

    有时候我们在项目中会遇到使用折线图等图形,Android的开源项目中为我们提供了很多插件,但是很多时候我们需要根据具体项目自定义这些图表,这一篇文章我们一起来看看如何在Android中使用Canvas ...

  9. Excel绘制动态图表 之 极品offset、多种控件动态动图

    1.案例1:辅助区域动态图 动态按钮“投资金额”的制作: "数据"菜单下"数据工作”组中的“数据验证”,选择"序列". 2. OFFSET ——函数中 ...

随机推荐

  1. How to get FlowLayoutPanel.AutoSize to work with FlowBreak

    have a problem with a FlowLayoutPanel and I don't know how to solve it. I'm placing two FlowLayoutPa ...

  2. [liu yanling]测试流程

    测试流程 1.制定测试计划 2.编辑测试用例 3.执行测试用例 4.发现并提交BUG 5.开发组修正BUG 6.对已修正BUG进行返测 7.修正完成的BUG将状态置为已关闭,未正确修正的BUG重新激活

  3. Maven详解 之 聚合与继承

    说到聚合与继承我们都很熟悉,maven同样也具备这样的设计原则,下面我们来看一下Maven的pom如何进行聚合与继承的配置实现. 一.为什么要聚合? 随着技术的飞速发展和各类用户对软件的要求越来越高, ...

  4. base64dll

    继上次的dll学习后,想开发个软件,连接到百度的云存储服务器,上传文件.发现要算秘钥,在网上找了到了hmac-sha1,base64的源码,发现有些是c++写的,有些是c写的一起写到一个文件里有些麻烦 ...

  5. bzoj 1875 [SDOI2009]HH去散步(矩乘)

    Description HH有个一成不变的习惯,喜欢饭后百步走.所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离. 但是同时HH又是个喜欢变化的人,所以他不会立刻沿着刚刚走来的路走回. 又因 ...

  6. (原)Struts 相关资源下载

    官网:http://struts.apache.org 点击[Download],进入页面如下,可以看到下载的资源: 点击[struts-2.3.20-all.zip],就能获取Struts2项目所有 ...

  7. CF_216_Div_2

    比赛链接:http://codeforces.com/contest/369 369C - Valera and Elections: 这是一个树上问题,用深搜,最开始贪心想得是只加叶子节点,找到一个 ...

  8. poj2186 Popular Cows(强连通)

    崇拜有传递性.求所有牛都崇拜的牛tarjan算法求强连通. 如果不连通就不存在.如果联通,缩点后唯一一个出度为零的点就是答案,有多个则不存在. #include <vector> #inc ...

  9. mysql group by 用法解析(详细)

    在使用mysql时,有时需要查询出某个字段不重复的记录,虽然mysql提供 有distinct这个关键字来过滤掉多余的重复记录只保留一条,但往往只用它来返回不重复记录的条数,而不是用它来返回不重记录的 ...

  10. Golang项目目录结构组织

    其实golang的工程管理还是挺简单的,完全使用目录结构还有package名来推导工程结构和构建顺序. 当然,首先要说的是环境变量$GOPATH,项目构建全靠它.这么说吧,想要构建一个项目,就要将这个 ...