Android使用AchartEngine绘制曲线图(一个点刷新一次)

首先说明下,这个里面的代码借鉴了网上的一些资源,总的来说很感谢,我做的工作就是简化新手的使用,写一个类,然后在主界面调用显示图表就会显得非常简单,这个有个前提1.大概了解下AchatgEngine的使用,然后你的工程项目中要导入这个架包(怎么导入的我就就不说了吧,呵呵,你懂的),2.刷新效果的实现必须依赖定时任务,定时任务可以用Handler和TimeTask或者Handler和postDelayed(Runnable, long)实现,可以参考如下:

Handler和postDelayed(Runnable, long),这个实现比较简单一些。

1. 定义一个Handler类

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

 

2. 启动计时器

handler.postDelayed(runnable, 2000);//每两秒执行一次runnable.  

3. 停止计时器

handler.removeCallbacks(runnable); 

三、采用Handler与timer及TimerTask结合的方法

1. 定义定时器、定时器任务及Handler句柄

 

private final Timer timer = new Timer();  
private TimerTask task;  
Handler handler = new Handler() {  
    @Override  
    public void handleMessage(Message msg) {  
        // TODO Auto-generated method stub  
        // 要做的事情  
        super.handleMessage(msg);  
    }  
}; 

 

2. 初始化计时器任务

task = new TimerTask() {  
    @Override  
    public void run() {  
        // TODO Auto-generated method stub  
        Message message = new Message();  
        message.what = 1;  
        handler.sendMessage(message);  
    }  
};   

3. 启动定时器

timer.schedule(task, 2000, 2000);

4. 停止计时器

timer.cancel();

我这里用的是task的方式,先看封装的类DynamicChart.java

package com.example.testchart;

import org.achartengine.ChartFactory;
import org.achartengine.GraphicalView;
import org.achartengine.chart.PointStyle;
import org.achartengine.model.XYMultipleSeriesDataset;
import org.achartengine.model.XYSeries;
import org.achartengine.renderer.XYMultipleSeriesRenderer;
import org.achartengine.renderer.XYSeriesRenderer;

import android.content.Context;
import android.graphics.Color;
import android.graphics.Paint.Align;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;

public class DynamicChart {
    private XYSeries series;
    private XYMultipleSeriesDataset mDataset;
    private XYMultipleSeriesRenderer renderer;
    private GraphicalView chart;
    private Context context;
    private LinearLayout layout;// 相当于图表的容器
    private String title = "Signal Strength";// 对应图表的标题
    private int addX = -1, addY;
    private int[] xv = new int[100];
    private int[] yv = new int[100];

    public LinearLayout getLayout() {
        return layout;
    }

    public Context getContext() {
        return context;
    }

    public void setContext(Context context) {
        this.context = context;
    }

    public void setLayout(LinearLayout layout) {
        this.layout = layout;
    }

    public DynamicChart() {// 无参构造方法
        super();
        // TODO Auto-generated constructor stub
    }

    public DynamicChart(Context context, LinearLayout layout) {//有参构造方法
        super();
        this.context = context;
        this.layout = layout;
    }

    public void init() {
        // 这个类用来放置曲线上的所有点,是一个点的集合,根据这些点画出曲线
        series = new XYSeries(title);
        // 创建一个数据集的实例,这个数据集将被用来创建图表
        mDataset = new XYMultipleSeriesDataset();
        // 将点集添加到这个数据集中
        mDataset.addSeries(series);
        // 以下都是曲线的样式和属性等等的设置,renderer相当于一个用来给图表做渲染的句柄
        renderer = buildRenderer(true);

        // 设置好图表的样式
        setChartSettings(renderer, 0, 100, 0, 90);

        // 生成图表
        chart = ChartFactory.getLineChartView(context, mDataset, renderer);

        // 将图表添加到布局中去
        layout.addView(chart, new LayoutParams(LayoutParams.MATCH_PARENT,
                LayoutParams.MATCH_PARENT));

    }

    /**
     * 基本上就是一些图标属性的设置
     * 
     * @param renderer
     * @param xMin
     * @param xMax
     * @param yMin
     * @param yMax
     */
    private void setChartSettings(XYMultipleSeriesRenderer renderer,
            double xMin, double xMax, double yMin, double yMax) {
        // 有关对图表的渲染可参看api文档
        // renderer.setMargins(new int[] { 50, 50, 50, 50 }); //
        // 设置图表的外边框(上/左/下/右)
        renderer.setChartTitle(title);// 设置图表的标题
        renderer.setXTitle("波长");// 设置横坐标标题
        renderer.setYTitle("A/D counts");// 设置纵坐标标题
         renderer.setChartTitleTextSize(20); // 设置整个图表标题文字大小
        renderer.setXAxisMin(xMin);// 设置x轴的最小值
        renderer.setXAxisMax(xMax);// 设置x轴的最大值
        renderer.setYAxisMin(yMin);// 设置y轴的最小值
        renderer.setYAxisMax(yMax);// 设置y轴的最大值
        renderer.setAxesColor(Color.BLACK);// 设置x\y轴的“直线”颜色
        renderer.setLabelsColor(Color.BLACK);// 设置xy和图标标题文字颜色
        renderer.setShowGrid(false);// 是否显示网格
        renderer.setGridColor(Color.GRAY);// 设置网格的颜色
        renderer.setAxisTitleTextSize(20); // 设置轴标题文字的大小
        renderer.setXLabels(20);
        renderer.setYLabels(10);
        renderer.setXLabelsAlign(Align.CENTER); // 刻度线与刻度标注之间的相对位置关系
        renderer.setYLabelsAlign(Align.RIGHT);// 刻度线与刻度标注之间的相对位置关系
        renderer.setPanEnabled(false, true); // 设置是否允许XY轴方向移动
        renderer.setPointSize((float) 2);//每个点所呈现的大小
        renderer.setShowLegend(false);// 是否显示图例
        renderer.setZoomEnabled(true);// 是否容许方法或缩小
        renderer.setZoomButtonsVisible(true);// 是否显示放大缩小按钮
        renderer.setApplyBackgroundColor(true); // 设置是否显示背景色
        renderer.setBackgroundColor(Color.WHITE);// 设置背景颜色
        renderer.setMarginsColor(Color.WHITE); // 设置外框颜色穿透背景色
        
    }

    private XYMultipleSeriesRenderer buildRenderer(boolean fill) {
        XYMultipleSeriesRenderer renderer = new XYMultipleSeriesRenderer();

        // 设置图表中曲线本身的样式,包括颜色、点的大小以及线的粗细等
        XYSeriesRenderer r = new XYSeriesRenderer();
        r.setColor(Color.GREEN);// 设置点的颜色
        r.setPointStyle(PointStyle.CIRCLE);// 点的类型(圆形、方形或者没有)
        r.setFillPoints(fill);
        r.setLineWidth(3);
        renderer.addSeriesRenderer(r);

        return renderer;
    }

    public void updateChart(int value) {

        // 设置好下一个需要增加的节点
        addX = 0;
        // addY = (int) (Math.random() * 90);
        addY = value;
        // 移除数据集中旧的点集
        mDataset.removeSeries(series);
        // 判断当前点集中到底有多少点,因为屏幕总共只能容纳100个,所以当点数超过100时,长度永远是100
        int length = series.getItemCount();
        if (length > 100) {
            length = 100;
        }
        // 将旧的点集中x和y的数值取出来放入backup中,并且将x的值加1,造成曲线向右平移的效果
        for (int i = 0; i < length; i++) {
            xv[i] = (int) series.getX(i) + 1;
            yv[i] = (int) series.getY(i);
        }
        // 点集先清空,为了做成新的点集而准备
        series.clear();

        // 将新产生的点首先加入到点集中,然后在循环体中将坐标变换后的一系列点都重新加入到点集中
        // 这里可以试验一下把顺序颠倒过来是什么效果,即先运行循环体,再添加新产生的点
        series.add(addX, addY);
        for (int k = 0; k < length; k++) {
            series.add(xv[k], yv[k]);
        }
        // 在数据集中添加新的点集
        mDataset.addSeries(series);

        // 视图更新,没有这一步,曲线不会呈现动态
        // 如果在非UI主线程中,需要调用postInvalidate(),具体参考api
        chart.invalidate();
    }

}
View Code

那么在Activity中调用就很简单了,看MainActivity中的代码:

package com.example.testchart;

import java.util.Timer;
import java.util.TimerTask;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.LinearLayout;

public class MainActivity extends Activity {
    private DynamicChart dynamicChart;
    private Timer timer = new Timer();
    private TimerTask task = new TimerTask() {
        
        @Override
        public void run() {
            // TODO Auto-generated method stub
            Message message = new Message();
            message.what = 1;
            handler.sendMessage(message);
        }
    };
    @SuppressLint("HandlerLeak")
    private Handler handler = new Handler(){

        @Override
        public void handleMessage(Message msg) {
            // TODO Auto-generated method stub
            super.handleMessage(msg);
            dynamicChart.updateChart((int) (Math.random() * 90));
        }};
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.test);
        dynamicChart = new DynamicChart(getApplicationContext(), (LinearLayout)findViewById(R.id.chartLayout1));
        dynamicChart.init();
        timer.schedule(task, 500, 500);
    }

}

当然你需要在你的视图xml文件中定义一个容器来存放图表:

    <LinearLayout
        android:id="@+id/chartLayout1"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:padding="10dip"
        android:background="#FFFFFF"
        android:orientation="vertical" >

然后来一张效果图:

 

posted @ 2015-05-04 19:55  tomi_mint  阅读(1192)  评论(4编辑  收藏  举报