Android绘制动态折线图

发布时间:2019-08-08 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了Android绘制动态折线图脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

所谓动态折线图,就是折线图能随着手指的滑动进行动态绘制,这里很定会产生动画效果。基于这个效果,这里使用SurfaceView进行制图。

实现步奏如下:

(1): 这里新建一个绘图ChartView,继承SurfaceView并实现SurfaceHolder.Callback , Runnable接口,主要绘图工作在子线程中完成。
(2):现实 SurfaceHolder.Callback接口的三个方法,并在 surfaceCreated中开启子线程进行绘图。
(3):重写onTouchEvent方法,在Move事件中,根据手指的滑动距离计算偏移量,具体实现请看代码。
(4): 这里的折线图的坐标值是随意添加的,可以在实际项目中根据需求自己添加。
(5):此例中有大量从集合中添加和删除元素,建议使用LinkedList来进行保存数据。

自定义ChartView:

 public class ChartView extends SurfaceView implements SurfaceHolder.Callback , Runnable {  PRivate Context mContext;  private Paint mPaint;  private Resources res;  private DisplayMetrics dm;   private int canvasHeight;  private int canvasWidth;  private int bHeight = 0;  private int bWidth;  private boolean isMeasure = true;  private boolean canScrollRight = true;  private boolean canScrollLeft = true;   //y轴最大值  private int maxValue;  //y轴间隔值  private int averageValue;  private int marginTop = 20;  private int marginBottom = 80;   //曲线上的总点数  private Point[] mPoints;  //纵坐标值  private LinkedList<Double> yRawData;  //横坐标值  private LinkedList<String> xRawData;  //根据间隔计算出的每个X的值  private LinkedList<Integer> xList = new LinkedList<>();  private LinkedList<String> xpredata = new LinkedList<>();  private LinkedList<Double> yPreData = new LinkedList<>();   private LinkedList<String> xLastData = new LinkedList<>();  private LinkedList<Double> yLastData = new LinkedList<>();  private int spacingHeight;   private SurfaceHolder holder;  private boolean isRunning = true;  private int lastX;  private int offSet;  private Rect mRect;   private int xAverageValue = 0;    public ChartView(Context context)  {   this(context , null);  }   public ChartView(Context context , AttributeSet attrs)  {   suPEr(context, attrs);   this.mContext = context;   inITView();  }   private void initView()  {   this.res = mContext.getResources();   this.mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);   dm = new DisplayMetrics();   WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);   wm.getDefaultDisplay().getMetrics(dm);    xPreData.add("05-18");   xPreData.add("05-17");   xPreData.add("05-16");   xPreData.add("05-15");   xPreData.add("05-14");   xPreData.add("05-13");    yPreData.add(4.53);   yPreData.add(3.45);   yPreData.add(6.78);   yPreData.add(5.21);   yPreData.add(2.34);   yPreData.add(6.32);    xLastData.add("05-26");   xLastData.add("05-27");   xLastData.add("05-28");   xLastData.add("05-29");   xLastData.add("05-30");   xLastData.add("05-31");    yLastData.add(2.35);   yLastData.add(5.43);   yLastData.add(6.23);   yLastData.add(7.33);   yLastData.add(3.45);   yLastData.add(2.45);    holder = this.getHolder();   holder.addCallback(this);  }   @override  protected void onSizeChanged(int w , int h , int oldW , int oldH)  {   if (isMeasure)   {    this.canvasHeight = getHeight();    this.canvasWidth = getWidth();    if (bHeight == 0)    {     bHeight = canvasHeight - marginBottom;    }    bWidth = dip2px(30);    xAverageValue = (canvasWidth - bWidth) / 7;    isMeasure = false;   }  }    @Override  public void run()  {   while (isRunning)   {    drawView();    try    {     Thread.sleep(100);    }    catch (InterruptedException e)    {     e.printStackTrace();    }   }  }   private void drawView()  {   Canvas canvas = holder.lockCanvas();   canvas.drawColor(Color.WHITE);   mPaint.setColor(res.getColor(R.color.color_f2f2f2));   drawAllXLine(canvas);   mRect = new Rect(bWidth - 3, marginTop - 5 ,     bWidth + (canvasWidth - bWidth) / yRawData.size() * (yRawData.size() - 1) + 3, bHeight + marginTop + marginBottom);   //锁定画图区域   canvas.clipRect(mRect);   drawAllYLine(canvas);    mPoints = getPoints();    mPaint.setColor(res.getColor(R.color.color_ff4631));   mPaint.setstrokeWidth(dip2px(2.5f));   mPaint.setStyle(Paint.Style.STROKE);   drawLine(canvas);    mPaint.setStyle(Paint.Style.FILL);   for (int i = 0 ; i < mPoints.length ; i++)   {    canvas.drawCircle(mPoints[i].x , mPoints[i].y , 5 , mPaint);   }    holder.unlockCanvasAndPost(canvas);  }   //绘制折线图  private void drawLine(Canvas canvas)  {   Point startP = null;   Point endP = null;   for (int i = 0 ; i < mPoints.length - 1; i++)   {    startP = mPoints[i];    endP = mPoints[i + 1];    canvas.drawLine(startP.x , startP.y , endP.x , endP.y , mPaint);   }  }   //绘制所有的纵向分割线  private void drawAllYLine(Canvas canvas)  {   for (int i = 0 ; i < yRawData.size() ; i++)   {    if (i == 0)    {     canvas.drawLine(bWidth, marginTop , bWidth, bHeight + marginTop , mPaint);    }    if (i == yRawData.size() - 1)    {     canvas.drawLine(bWidth + xAverageValue * i, marginTop , bWidth + xAverageValue * i , bHeight + marginTop , mPaint);    }    xList.add(bWidth + xAverageValue * i);    canvas.drawLine(bWidth + xAverageValue * i + offSet, marginTop , bWidth + xAverageValue * i + offSet , bHeight + marginTop , mPaint);    drawText(xRawData.get(i) , bWidth + xAverageValue * i - 30 + offSet, bHeight + dip2px(26) , canvas);    }  }   //绘制所有的横向分割线  private void drawAllXLine(Canvas canvas)  {   for (int i = 0 ; i < spacingHeight + 1 ; i++)   {    canvas.drawLine(bWidth , bHeight - (bHeight / spacingHeight) * i + marginTop ,      bWidth + xAverageValue * (yRawData.size() - 1) , bHeight - (bHeight / spacingHeight) * i + marginTop , mPaint);    drawText(String.valueOf(averageValue * i) , bWidth / 2 , bHeight - (bHeight / spacingHeight) * i + marginTop, canvas);   }  }   //绘制坐标值  private void drawText(String text , int x , int y , Canvas canvas)  {   Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);   p.setTextSize(dip2px(12));   p.setColor(res.getColor(R.color.color_999999));   p.setTextAlign(Paint.Align.LEFT);   canvas.drawText(text , x , y , p);  }   @Override  public void surfaceCreated(SurfaceHolder surfaceHolder)  {   new Thread(this).start();   LOG.d("OOK" , "Created");  }   @Override  public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2)  {   Log.d("OOK" , "Changed");  }   @Override  public void surfaceDestroyed(SurfaceHolder surfaceHolder)  {   isRunning = false;   try   {    Thread.sleep(500);   }   catch (InterruptedException e)   {    e.printStackTrace();   }  }   @Override  public boolean onTouchEvent(MotionEvent event)  {   int action = event.getAction();   int rAWX = (int) event.getX();   switch (action)   {    case MotionEvent.ACTION_DOWN:     lastX = rawX;     break;    case MotionEvent.ACTION_MOVE:     int offsetX = rawX - lastX;     if (xPreData.size() == 0 && offSet > 0)     {      offSet = 0;      canScrollRight = false;     }     if (xLastData.size() == 0 && offSet < 0)     {      offSet = 0;      canScrollLeft = false;     }     offSet = offSet + offsetX;     if (offSet > xAverageValue && canScrollRight)     {      offSet = offSet % xAverageValue;      xRawData.addFirst(xPreData.pollFirst());      yRawData.adDFirst(yPreData.pollFirst());      xLastData.addFirst(xRawData.removeLast());      yLastData.addFirst(yRawData.removeLast());      canScrollLeft = true;     }       if (offSet < -xAverageValue && canScrollLeft)     {      offSet = offSet % xAverageValue;      xRawData.addLast(xLastData.pollFirst());      yRawData.addLast(yLastData.pollFirst());      xPreData.addFirst(xRawData.removeFirst());      yPreData.addFirst(yRawData.removeFirst());      canScrollRight = true;     }     lastX = rawX;     break;    case MotionEvent.ACTION_UP:     break;   }   return true;  }   private Point[] getPoints()  {   Point[] points = new Point[yRawData.size()];   for (int i = 0 ; i < yRawData.size() ; i++)   {    int ph = bHeight - (int)(bHeight * (yRawData.get(i) / maxValue));     points[i] = new Point(xList.get(i) + offSet , ph + marginTop);   }   return points;  }   public void setData(LinkedList<Double> yRawData , LinkedList<String> xRawData , int maxValue , int averageValue)  {   this.maxValue = maxValue;   this.averageValue = averageValue;   this.mPoints = new Point[yRawData.size()];   this.yRawData = yRawData;   this.xRawData = xRawData;   this.spacingHeight = maxValue / averageValue;  }   private int dip2px(float dpvalue)  {   return (int) (dpValue * dm.density + 0.5f);  } }

MainActivity代码:

 public class MainActivity extends Activity {  LinkedList<Double> yList;  LinkedList<String> xRawData;  ChartView chartView;  @Override  protected void onCreate(Bundle savedInstancestate)  {   super.onCreate(savedInstanceState);   setContentView(R.layout.main_activity);   chartView = (ChartView) findViewById(R.id.chartView);    yList = new LinkedList<>();   yList.add(2.203);   yList.add(4.05);   yList.add(6.60);   yList.add(3.08);   yList.add(4.32);   yList.add(2.0);   yList.add(5.0);    xRawData = new LinkedList<>();   xRawData.add("05-19");   xRawData.add("05-20");   xRawData.add("05-21");   xRawData.add("05-22");   xRawData.add("05-23");   xRawData.add("05-24");   xRawData.add("05-25");    chartView.setData(yList , xRawData , 8 , 2);  } }

此例页面布局比较简单,就是在主页面布局中添加一个自定义的ChartView即可,这里不再贴出。可能写得有点仓促,如果不妥之处,请大家批评指正,谢谢!

android教程
脚本网站
android studio

脚本宝典总结

以上是脚本宝典为你收集整理的Android绘制动态折线图全部内容,希望文章能够帮你解决Android绘制动态折线图所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。