Android 绘制动态图

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

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

    

制作的整体思路:

  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 绘制动态图,布布扣,bubuko.com

时间: 2024-12-04 23:06:50

Android 绘制动态图的相关文章

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

有时候我们在项目中会遇到使用折线图等图形,Android的开源项目中为我们提供了很多插件,但是很多时候我们需要根据具体项目自定义这些图表,这一篇文章我们一起来看看如何在Android中使用Canvas绘制折线图.先看看绘制的效果: 代码: public class MyView extends View { //坐标轴原点的位置 private int xPoint=60; private int yPoint=260; //刻度长度 private int xScale=8;  //8个单位构

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

有时候我们在项目中会遇到使用折线图等图形,Android的开源项目中为我们提供了很多插件,但是很多时候我们需要根据具体项目自定义这些图表,这一篇文章我们一起来看看如何在Android中使用Canvas绘制折线图.先看看绘制的效果: 实现原理很简单,我就直接给出代码: package com.example.testcanvasdraw; import java.util.ArrayList; import java.util.List; import java.util.Random; impo

Android 自定义绘制折线图(重点是Y轴的公式)

/** * 绘制折线图的公式Y轴坐标: y=height-((data-min)/(max-min))*height; 可以得到data在Y轴的坐标点 * height: 折线图 Y轴的坐标 * data: 数据源 * max: 数据源的最大值 * min: 数据源的最小值 * * */ /** * 绘制折线图: y轴左侧的数据 * * 1.根据需求 :显示几个数据 height/显示个数(平均分配Y轴) * 2.左侧数据: Y轴的顶部:数据源max值 Y轴的底部:数据源的min值 中间数据:取

Android编程动态创建视图View的方法

在Android开 发中,在Activity中关联视图View是一般使用setContentView方法,该方法一种参数是使用XML资源直接创 建:setContentView (int layoutResID),指定layout中的一个XML的ID即可,这种方法简单.另一个方法是 setContentView(android.view.View),参数是指定一个视图View对象,这种方法可以使用自定义的视图类. 在一些场合中,需要对View进行一些定制处理,比如获取到Canvas进行图像绘制,

使用andbase开发框架实现绘制折线图

在Android中,当有绘制折线图的需求时,大多数人使用的AChartEngine,来进行折线图的绘制.AChartEngine图表引擎确实可以实现折线图的功能,除此之外,我们还可以使用andbase开发框架里面的图表模块,实现图标的绘制.前面文章介绍了使用andbase开发框架实现侧滑栏效果,今天,我们学习如何实现折线的绘制. 首先,我们还是看一下效果图 我们模拟的是一家公司12个月中,两项不同业务的销售额变化,可以看到,效果还是非常不错的. 下面,我们开始介绍如何使用andbase实现这个效

Morris.js和flot绘制折线图的比较

[文章摘要] 最近用开源的AdminLTE做框架感觉效果特别好,其针对图表库Morris.js和flot都提供了不错的支持,也都提供了这两者的例子.不过Morris.js是基于Raphael.js来的,也就是其使用SVG和VML来绘制图形,而flot则是使用Canvas进行绘制,在绘制效率和浏览器兼容性等方面会有出入,同时两者需要的数据格式也不相同.本文中对两者的使用和性能进行了比较. [文章索引] Morris.js的使用 flot的使用 性能比较 [一.Morris.js的使用] Morri

【MFC】MFC绘制动态曲线,用双缓冲绘图技术防闪烁

摘自:http://zhy1987819.blog.163.com/blog/static/841427882011614103454335/ MFC绘制动态曲线,用双缓冲绘图技术防闪烁 2011-07-14 10:34:54|  分类: 学习笔记 |  标签:双缓冲绘图技术  mfc  动态曲线   |举报 |字号 订阅 先上效果图 随着时间的推移,曲线向右平移,同时X轴的时间坐标跟着更新.一.如何绘制动态曲线. 所谓动画,都是一帧一帧的图像连续呈现在用户面前形成的.所以如果你掌握了如何绘制静

Android绘制优化(二)布局优化

相关文章 Android绘制优化(一)绘制性能分析 前言 我们知道一个界面的测量和绘制是通过递归来完成的,减少布局的层数就会减少测量和绘制的时间,从而性能就会得到提升.当然这只是布局优化的一方面,那么如何来进行布局的分析和优化呢?本篇文章会给你一个满意的答案. 1.布局优化工具 在讲到如何去布局优化前,我们先来学习两种布局优化的工具. Hierarchy Viewer Hierarchy Viewer是Android SDK自带的可视化的调试工具,用来检查布局嵌套和绘制的时间.需要注意的是在在A

Android绘制优化(一)绘制性能分析

前言 一个优秀的应用不仅仅是要有吸引人的功能和交互,同时在性能上也有很高的要求.运行Android系统的手机,虽然配置在不断的提升,但仍旧无法和PC相比,无法做到PC那样拥有超大的内存以及高性能的CPU,因此在开发Android应用程序时也不可能无限制的使用CPU和内存,如果对CPU和内存使用不当也会造成应用的卡顿和内存溢出等问题.因此,应用的性能优化对于开发人员有着更高的要求.Android性能优化分为很多种,比较常用的有绘制优化.内存优化.耗电优化和稳定性优化等,这个系列我们就来学习性能优化