仿ES界面写的文件浏览器
http://www.eoeandroid.com/thread-226511-1-1.html

Android 新版捕鱼达人源码
http://www.eoeandroid.com/thread-197437-1-1.html

Android的学习初体验猜牌游戏源码
http://www.eoeandroid.com/thread-163542-1-1.html

实现这个的目的是为了在手机屏幕上能够动态显示接收的数据,适合哪种不断有新数据接收时需要时时展现的程序。
首先我们采用的实现方式是:SurfaceView的onDraw实现,初始化一个view,画已有的点,提供添加点的接口给它的Activity调用,onDraw方法要实现根据点的数组画点。
首先我利用了以前写的一个游戏的VIew它实现了不间断的调用onDraw,这样才能保证点是一直跑动的,代码:

  import android.content.Context; import android.graphics.Canvas; import android.util.AttributeSet; import android.util.Log; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.SurfaceHolder; import android.view.SurfaceView; /**  *   * Copyright (c) 2012 All rights reserved  * 名称:GameView.java   * 描述:继承自该类的view只需要考虑怎么绘制画面  * 需要实现draw(Canvas canvas)方法  * 注意:实现的draw方法中不要锁定、解锁画布  * 不要进行异常处理  * @author zhaoqp  * @date:2012-10-30 下午4:42:32  * @version v1.0  */ public abstract class GameView extends SurfaceView implements SurfaceHolder.Callback{    private static final String TAG = "GameView";  public ViewThread thread;   //刷帧的线程  //定义SurfaceHolder对象  private SurfaceHolder mSurfaceHolder = null;  public String fps="FPS:N/A";          //用于显示帧速率的字符串,调试使用  private boolean loop = true;  private boolean pause = true;  //睡眠的毫秒数   private int sleepSpan = 100;  public GameView(Context context){   super(context);   init();  }    public GameView(Context context, AttributeSet attrs, int defStyle) {   super(context, attrs, defStyle);   init();  }  public GameView(Context context, AttributeSet attrs) {   super(context, attrs);   init();  }    public void init(){   //Log.d(TAG, "--GameView Created--");   // 实例化SurfaceHolder   mSurfaceHolder = this.getHolder();   // 添加回调   mSurfaceHolder.addCallback(this);   this.setFocusable(true);   thread = new ViewThread(mSurfaceHolder,this);   thread.start();  }  /**   * 设置刷新的sleep间隔时间   */  public void setSleep(int time){   this.sleepSpan = time;  }    /**      * 设置循环标记位      * @param loop      */     public void setLoop(boolean loop) {      this.loop = loop;     }         /**     * 设置循环暂停标记位     * @param pause     */    public void setPause(boolean pause) {         this.pause = pause;    }    /**   * 绘图   */  public abstract void onDraw(Canvas canvas);    /**   * 在surface创建时激发的扩展方法   */  public void expandSurfaceCreated(){  }  /**   * 在surface创建时激发的扩展方法   */  public void expandSurfaceDestroyed(){  }    /**   * 在surface的大小发生改变时激发   */  @Override  public void surfaceChanged(SurfaceHolder holder, int format, int width, int height){  }  /**   * 在surface销毁时激发   */  @Override  public void surfaceCreated(SurfaceHolder holder){    //如果后台重绘线程没起来,就启动它    if(! this.thread.isAlive()){           try{            //启动刷帧线程            this.setLoop(true);            this.setPause(true);            this.thread.start();            expandSurfaceCreated();           }catch(Exception e){            e.printStackTrace();            this.setLoop(false);            this.setPause(false);           }                   }   Log.d(TAG, "--surfaceCreated--");  }  /**   * 在surface销毁时激发   */  @Override  public void surfaceDestroyed(SurfaceHolder holder){         releaseViewThread();         Log.d(TAG, "--surfaceDestroyed--");  }    /**   * 释放view类线程   */  public void releaseViewThread(){   if(thread != null && thread.isAlive()){    this.setPause(false);    this.setLoop(false);     try {                  thread.interrupt();           }catch (Exception e) {               e.printStackTrace();           }   }   thread = null;  }    /**   * 触摸屏事件   * @param event   */  public void onMyTouchEvent(MotionEvent event){  }    /**   * 按键事件按下   * @param keyCode   * @param event   */  public void onMyKeyDown(int keyCode, KeyEvent event) {  }    /**   * 按键事件抬起   * @param keyCode   * @param event   */  public void onMyKeyUp(int keyCode, KeyEvent event) {  }       /**      * 滚动事件      * @param event      */  public void onMyTrackballEvent(MotionEvent event) {  }    /**   * 刷帧线程   */  class ViewThread extends Thread{      private SurfaceHolder surfaceHolder;   private GameView gameView;   private int count = 0;              //记录帧数,该变量用于计算帧速率   private long start = System.nanoTime(); //记录起始时间,该变量用于计算帧速率   /**    * 构造方法    * @param surfaceHolder    * @param gameView    */         public ViewThread(SurfaceHolder surfaceHolder, GameView gameView) {             this.surfaceHolder = surfaceHolder;             this.gameView = gameView;         }            @Override   public void run() {    Canvas canvas;             while (loop) {                while (pause) {              canvas = null;                 try {                  if(!Thread.currentThread().isInterrupted()){                   //锁定整个画布,在内存要求比较高的情况下,建议参数不要为null                   canvas = this.surfaceHolder.lockCanvas();                         synchronized (this.surfaceHolder) {                          gameView.onDraw(canvas);//绘制                         }                  }                 }catch (Exception e){         e.printStackTrace();         Thread.currentThread().interrupt();         loop = false;        }finally {                     if (canvas != null) {                      //更新屏幕显示内容                         this.surfaceHolder.unlockCanvasAndPost(canvas);                     }                 }        this.count++;        if(count == 20){ //如果计满20帧         count = 0;  //清空计数器         long tempStamp = System.nanoTime(); //获取当前时间         long span = tempStamp - start;  //获取时间间隔         start = tempStamp;     //为start重新赋值         double fps = Math.round(100000000000.0/span*20)/100.0;//计算帧速率         gameView.fps = "FPS:"+fps;//将计算出的帧速率设置到gameView的相应字符串对象中        }                 try{                  Thread.sleep(sleepSpan);  //睡眠指定毫秒数                 }catch(Exception e){                  e.printStackTrace();      //打印堆栈信息                 }              }     }     }  } }

接下来实现这个View

这个View要实现能够根据数组中的点时时绘制,其中x轴每个单位的间距我设置为50,通过offect实现点的慢移动,代码:
  public class VisualizerView extends GameView {  private float[] mPoints;  private float[] mPointsDraw;  // 画笔  private Paint mPaint = new Paint();  private int offect = 0;  // 初始化画笔  private void init1() {   mPaint.setAntiAlias(true);   mPaint.setFakeBoldText(true);   mPaint.setTextSize(13);  }  public VisualizerView(Context context) {   super(context);   init1();  }  public VisualizerView(Context context, AttributeSet attr) {   super(context, attr);   init1();  }  public void updateVisualizer(float[] points) {    if(points != null){     this.mPoints = points;     mPointsDraw = new float[points.length-1];     System.out.println("新点旧加入");     offect = 0;    }    //一个点进来  要执行多次onDraw,将点缓缓移动    //移动50次    //invalidate();  }  @Override  public void onDraw(Canvas canvas) {   canvas.drawColor(Color.WHITE);   mPaint.setStrokeWidth(0.2f);   //底线   mPaint.setColor(Color.RED);   //canvas.drawLine(0, getHeight(), getWidth(), getHeight(), mPaint);   //顶线   mPaint.setColor(Color.RED);   //canvas.drawLine(0, 0, getWidth(), 0, mPaint);   //中线   mPaint.setColor(Color.GRAY);   canvas.drawLine(0, getHeight()/2, getWidth(),getHeight()/2, mPaint);   //每个单位20大小   //99   mPaint.setColor(Color.RED);   canvas.drawLine(0, getHeight()/2+40,getWidth(),getHeight()/2+40, mPaint);   //95   canvas.drawLine(0, getHeight()/2-40,getWidth(),getHeight()/2-40, mPaint);      mPaint.setColor(Color.GRAY);   canvas.drawText("99", 0, getHeight()/2-42, mPaint);   canvas.drawText("95", 0, getHeight()/2+40, mPaint);      if (mPoints != null && mPoints.length>1) {    mPointsDraw = new float[99];    //把中线认为是97,计算点的偏移    for (int i = 1; i < mPoints.length; i++) {     if(mPoints[i]!=0){      float offect = mPoints[i]-97;      offect = offect*20;      mPointsDraw[i-1] = getHeight()/2-offect;     }else{      mPointsDraw[i-1] = 97;     }    }        mPaint.setStrokeWidth(1f);    //最后结果    for (int i = 0; i < mPointsDraw.length; i++) {     mPaint.setColor(Color.GRAY);     canvas.drawCircle(50*i-offect,mPointsDraw[i], 2, mPaint);     canvas.drawText(String.valueOf((int)mPoints[i+1]), (float)50*i-offect-10, mPointsDraw[i]-3, mPaint);     mPaint.setColor(Color.BLUE);     canvas.drawLine(50*i-offect, mPointsDraw[i], 50*(i+1)-offect,mPointsDraw[i], mPaint);    }        if(offect<50){     offect+=10;    }       }  }   }

首先要在顶层布局中写上view的schemas: 

<com.chxue8.view.VisualizerView           android:id="@+id/mVisualizerView" android:layout_width="400dip"  android:layout_height="200dip"  android:layout_marginTop="40dip"  android:layout_marginLeft="20dip"              > </com.chxue8.view.VisualizerView>
    VisualizerView mVisualizerView = (VisualizerView) findViewById(R.id.mVisualizerView);   float[] pointFloat = null;   pointFloat = new float[100];   pointFloat[0] = 0;//数组第一位哨兵 保存当前大小   pointFloat[1] = 97; //预留的值  

当有新数据过来

   int size  = (int)pointFloat[0];     pointFloat[size++] = (float)spo_str;     pointFloat[0] = size;     //向前移动     if(size>=pointFloat.length){      for(int i=2;i<pointFloat.length;i++){       pointFloat[i-1] = pointFloat[i];       }      size--;      pointFloat[0] = size;     }     c++;  //由于数据量太大了,没10个点取一个更新到图表上     if(c%10==0){      mVisualizerView.updateVisualizer(pointFloat);      c = 0;     }


效果图 :

在android中实现动态跑动的图表实现方法

更多相关文章

  1. Android service的开启和绑定,以及调用service的方法
  2. Android中JNI的使用方法
  3. 【解决方法】Unexpected namespace prefix “xmlns” found for
  4. Android Studio下“Error:Could not find com.android.tools.bui
  5. Android 结束进程的方法
  6. Android 常用的画图方法
  7. Android中Sample的使用方法

随机推荐

  1. Android视图绘制流程完全解析,带你一步步
  2. Android(安卓)自定义组合控件
  3. 【Android自动化打包】03. APK的数字签名
  4. 一场关于Android的争论
  5. Android(安卓)开机启动应用
  6. Android调用WebService系列之封装能力
  7. adb通过TCP/IP来调试Android设备
  8. 2016这一年,回顾我们一起走过的"编码美丽"
  9. Unity导出android工程集成到android stud
  10. Android版本管理解决方法小议