欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android实现折线走势图

程序员文章站 2023-10-31 08:51:58
本文实例为大家分享了android折线走势图的具体代码,供大家参考,具体内容如下 先来看看效果图 可以根据球的数量动态的改变自己的球半径,以及线宽 代码实现也是超级简单...

本文实例为大家分享了android折线走势图的具体代码,供大家参考,具体内容如下

先来看看效果图

Android实现折线走势图

可以根据球的数量动态的改变自己的球半径,以及线宽

Android实现折线走势图

代码实现也是超级简单

//获取自定义属性
private void obtainstyledattrs(attributeset attrs) {
  typedarray typedarray = getcontext().obtainstyledattributes(attrs,r.styleable.high_lowchartview);
  mtextsize = (int)typedarray.getdimension(r.styleable.high_lowchartview_hl_chart_textsize,mtextsize);
  mtextcolor = typedarray.getcolor(r.styleable.high_lowchartview_hl_chart_textcolor,mtextcolor);
  if (typedarray.getstring(r.styleable.high_lowchartview_hl_hchart_text)!=null){
   mhightext = typedarray.getstring(r.styleable.high_lowchartview_hl_hchart_text);
  }
  if(typedarray.getstring(r.styleable.high_lowchartview_hl_hchart_text)!=null){
   mlowtext = typedarray.getstring(r.styleable.high_lowchartview_hl_hchart_text);
  }
  mhighpointcolor = typedarray.getcolor(r.styleable.high_lowchartview_hl_chart_high_pointcolor,mhighpointcolor);
  mlowpointcolor = typedarray.getcolor(r.styleable.high_lowchartview_hl_chart_low_pointcolor,mlowpointcolor);
  mmainlinecolor = typedarray.getcolor(r.styleable.high_lowchartview_hl_chart_mianlinecolor,mmainlinecolor);
  mchartlinecolor = typedarray.getcolor(r.styleable.high_lowchartview_hl_chart_chartlinecolor,mchartlinecolor);
  mchartdistance = (int) typedarray.getdimension(r.styleable.high_lowchartview_hl_chart_distance,mchartdistance);

  init();
  typedarray.recycle();
 }

//重写onmeasure
 @override
 protected void onmeasure(int widthmeasurespec, int heightmeasurespec) {
  super.onmeasure(widthmeasurespec, heightmeasurespec);
  int width = measurespec.getsize(widthmeasurespec);
  int height = measureheight(heightmeasurespec);
  setmeasureddimension(width,height);

 }
//计算view需要的高度
 private int measureheight(int heightmeasurespec) {
  int result = 0;
  int mode = measurespec.getmode(heightmeasurespec);
  int size = measurespec.getsize(heightmeasurespec);
  if(mode == measurespec.exactly){//如果给了具体值则直接用
   result=size;
  }else {
  //否则高度等于字高与球直径的最大值
   textheight = (mpaint.descent()-mpaint.ascent());
   float halfheight = math.max(textheight, mpointmaxheight) / 2;
   result = (int) (halfheight+mchartdistance);
   //如果模式为at_most即:测量高度不能超过父类给定的高度则取测量结果与size的最小值
   if(mode==measurespec.at_most){
    result = math.min(result,size);
   }
  }
  return result;
 }

 @override
 protected void ondraw(canvas canvas) {
  super.ondraw(canvas);
  if(!initmeasure()) return;
  canvas.save();
  //1先画两条主线
  mpaint.setcolor(mmainlinecolor);
  mpaint.setstrokewidth(mainlineheight);

  //high line
  canvas.drawline(textwidth+default_offsetting,mainlineposition,w,mainlineposition,mpaint);
  //low line
  canvas.drawline(textwidth+default_offsetting,mainlineposition+mchartdistance,w,mainlineposition+mchartdistance,mpaint);

  //2再画文字
  mpaint.setcolor(mtextcolor);
  mpaint.settextalign(paint.align.left);
  paint.fontmetricsint fontmetrics = mpaint.getfontmetricsint();
  rectf rt1=new rectf(0,mainlineposition-textheight/2,w,mainlineposition+textheight/2);
  int baseline = (int) ((rt1.bottom + rt1.top - fontmetrics.bottom - fontmetrics.top) / 2);
  canvas.drawtext(mhightext,0,baseline,mpaint);
  canvas.drawtext(mlowtext,0,baseline+mchartdistance,mpaint);

  //3初始化小球圆心
  canvas.translate(textwidth+default_offsetting,0);

  for (int i=0;i<mpointnum;i++){
   //high point
   if (mlist.get(i).ishighpoint){
//    mpaint.setcolor(mhighpointcolor);
//    canvas.drawcircle((pointheight/2+offsetx)+i*(pointheight+offsetx), mainlineposition, pointheight/2, mpaint);
    //存入小球的圆心坐标
    mlist.get(i).setxy((pointheight/2+offsetx)+i*(pointheight+offsetx),mainlineposition);
   }else {
    //low point
//    mpaint.setcolor(mlowpointcolor);
//    canvas.drawcircle((pointheight/2+offsetx)+i*(pointheight+offsetx), mainlineposition+mchartdistance, pointheight/2, mpaint);
    mlist.get(i).setxy((pointheight/2+offsetx)+i*(pointheight+offsetx),mainlineposition+mchartdistance);
   }
  }
  //4连接小球
  if(mlist.size()>=2){
   mpaint.setcolor(mchartlinecolor);
   mpaint.setstrokewidth(chartlinewidth);
   for (int i=0;i<mpointnum-1;i++){
    canvas.drawline(mlist.get(i).cx,mlist.get(i).cy,mlist.get(i+1).cx,mlist.get(i+1).cy,mpaint);
   }
  }
  //5绘制小球(为了不让线遮盖小球)
  for (int i=0;i<mpointnum;i++){
   //high point
   if (mlist.get(i).ishighpoint){
    mpaint.setcolor(mhighpointcolor);
    //low point
   }else {
    mpaint.setcolor(mlowpointcolor);
   }
   canvas.drawcircle(mlist.get(i).cx, mlist.get(i).cy, pointheight/2, mpaint);
  }
  canvas.restore();
 }

 /**
  * 根据小球数量去动态测量一些属性
  * @return
  */
 private boolean initmeasure() {
  //根据传进来的point数量计算小点的大小,mainline的线宽,折线的线宽
   /* 如果小球数量在1-10个,主线高度为3dip
   * 如果小球数量在10-20个,主线高度设置为2dip
   * 如果小球数量超过20个,主线高度设置为1dp
   */
  mpointnum=mlist.size();
//  if(mpointnum==0) return false;
  if(10>mpointnum){
   mainlineheight=dp2px(3);
  }else if(10<=mpointnum&&20>mpointnum){
   mainlineheight = dp2px(2);
  }else {
   mainlineheight = dp2px(1);
  }

  //主线长度等于总宽度-(文字宽度+30px)
  textwidth=math.max(mpaint.measuretext(mhightext),mpaint.measuretext(mlowtext));
  mainlinewidth = (int) (w-(textwidth+default_offsetting));

  /*小球直径应该由主线长度与小球数量决定*/
  //理想直径
  float ideadia = mainlinewidth / (mpointnum + (mpointnum + 1));
  //小球直径不能大于最大直径
  if(ideadia>mpointmaxheight){
//   log.i("ttt","ideadia>mpointmaxheight");
   pointheight = mpointmaxheight;
   offsetx=(mainlinewidth-mpointnum*pointheight)/(mpointnum+1);
   //(极端情况)如果小球直径小于线高,为小球直径+2px
  }else if(ideadia<=mainlineheight){
//   log.i("ttt","ideadia<=mpointmaxheight");
   pointheight = mainlineheight+2;
   offsetx=(mainlinewidth-mpointnum*pointheight)/(mpointnum+1);
  }else {
//   log.i("ttt"," pointheight=offsetx=ideadia");
   pointheight=offsetx=ideadia;
  }
  //主线位置
  mainlineposition = (h-mchartdistance)/2;
  //折线宽度
  chartlinewidth = mainlineheight/2;
  return true;
 }

//刷新小球集合
 public void setpointlist(list<aiyingpoint> list){
  if (list==null&&list.size()==0) return;
  mlist.clear();
  if (list.size()>150) {
   mlist.addall(list.sublist(0,150));
  } else {
   mlist.addall(list);
  }
  invalidate();
 }

使用示例

<com.android.view.high_lowchartview
   android:id="@+id/hl_chart"
   android:layout_below="@+id/tv_state"
   android:layout_marginleft="15dp"
   android:layout_marginright="15dp"
   android:layout_width="match_parent"
   android:layout_height="70dp"
   app:hl_chart_mianlinecolor="#cdcdcd"
   app:hl_chart_distance="55dp"
   app:hl_chart_low_pointcolor="#999999"
   app:hl_chart_high_pointcolor="#f70919"
   app:hl_chart_textsize="13sp"
   app:hl_chart_textcolor="#2f2f2f"
   app:hl_chart_chartlinecolor="#999999"
 />

好了这样折线图就绘制完成了,是不是很简单呢?

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。