android开发分享android实现可以滑动的平滑曲线图

本文实例为大家分享了android实现可以滑动的平滑曲线图的具体代码,供大家参考,具体内容如下直接上代码,里面有详细注解1 attr 属性编写 <!– xy坐标轴颜色 –><at

android开发分享android实现可以滑动的平滑曲线图实例为大家分享了android实现可以滑动的平滑曲线图的具体代码,供大家参考,具体内容如下

上述就是android开发分享android实现可以滑动的平滑曲线图的全部内容,如果对大家有所用处且需要了解更多关于Android学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!

直接上代码,里面有详细注解

1 attr 属性编写   

<!-- xy坐标轴颜色 -->    <attr name="xy_line_color" format="color" />      <!-- xy坐标轴宽度 -->      <attr name="xy_line_width" format="dimension" />      <!-- xy坐标轴文字颜色 -->      <attr name="xy_text_color" format="color" />      <!-- xy坐标轴文字大小 -->      <attr name="xy_text_size" format="dimension" />      <!-- 折线图中折线的颜色 -->      <attr name="line_color" format="color" />      <!-- x轴各个坐标点水平间距 -->      <attr name="interval" format="dimension" />      <!-- 背景颜色 -->      <attr name="bg_color" format="color" />      <!-- 曲线选中外部颜色 -->      <attr name="select_circle_color" format="color" />      <!-- 曲线选中内部颜色 -->      <attr name="select_reminder_color" format="color" />      <!--是否抬手滚动-->      <attr name="isscroll" format="boolean" />      <declare-styleable name="chartview">          <attr name="xy_line_color" />          <attr name="xy_line_width" />          <attr name="xy_text_color" />          <attr name="xy_text_size" />          <attr name="line_color" />          <attr name="interval" />          <attr name="bg_color" />          <attr name="select_circle_color" />          <attr name="select_reminder_color" />          <attr name="isscroll" />          <!--提示框跟滑动显示的位置-->          <attr name="show_position">              <enum name="first" value="1" />              <enum name="middle" value="2" />              <enum name="end" value="3" />          </attr>  </declare-styleable>

2 chartview

package com.laisontech.commonuilibrary.customviews;    import android.animation.animator;  import android.animation.valueanimator;  import android.content.context;  import android.content.res.typedarray;  import android.graphics.canvas;  import android.graphics.color;  import android.graphics.paint;  import android.graphics.path;  import android.graphics.porterduff;  import android.graphics.porterduffxfermode;  import android.graphics.rect;  import android.graphics.rectf;  import android.util.attributeset;  import android.util.log;  import android.util.typedvalue;  import android.view.motionevent;  import android.view.velocitytracker;  import android.view.view;  import android.view.animation.decelerateinterpolator;    import com.laisontech.commonuilibrary.r;    import java.util.arraylist;  import java.util.hashmap;  import java.util.list;  import java.util.map;    /**   * 自定义折线图   */  public class chartview extends view {      private static final int first = 1;      private static final int middle = 2;      private static final int end = 3;      //xy坐标轴颜色      private int xylinecolor = 0xffcfe2cf;      //折线选中的圆形颜色      private int selectcirclecolor = 0xff00a8ff;      //选中数据提示框颜色      private int selectremindercolor = 0xff00a8ff;      //折线中圆形内部部颜色      private int xytextcolor = 0xff0014ff;      //折线图中折线的颜色      private int linecolor = 0xfffd00ff;      //xy坐标轴宽度      private int xylinewidth = dptopx(1);      //xy坐标轴文字大小      private int xytextsize = sptopx(12);      //x轴各个坐标点水平间距      private int interval = dptopx(40);      //背景颜色      private int bgcolor = 0xffffffff;      //是否有起手时的滑动感      private boolean isscroll = false;      //提示框显示位置      private int mshowpositiontype = 3;      //绘制xy轴坐标对应的画笔      private paint mxypaint;      //绘制xy轴的文本对应的画笔      private paint mxytextpaint;      //画折线对应的画笔      private paint mspinnerlinepaint;      private int width;      private int height;      //x轴的原点坐标      private int mxori;      //y轴的原点坐标      private int myori;      //第一个点x的坐标      private float mxinit;      //第一个点对应的最大x坐标      private float maxxinit;      //第一个点对应的最小x坐标      private float minxinit;      //x轴坐标对应的数据      private list<string> mxdata = new arraylist<>();      //y轴坐标对应的数据      private list<integer> mydata = new arraylist<>();      //折线对应的数据      private map<string, integer> mspinnervalue = new hashmap<>();      //点击的点对应的x轴的第几个点,默认1      private int selectindex = 1;      //x轴刻度文本对应的最大矩形,为了选中时,在x轴文本画的框框大小一致,获取从数据中得到的x轴数据,获得最长数据      private rect xvaluerect;      //速度检测器      private velocitytracker mtracker;      //是否为短距离滑动      private boolean isshortslide = false;      //获取尺寸的的中间      private int mselectmiddle = 0;      //曲线切率      private float mlinesmoothness = 0.18f;        public chartview(context context) {          this(context, null);      }        public chartview(context context, attributeset attrs) {          this(context, attrs, 0);      }        public chartview(context context, attributeset attrs, int defstyleattr) {          super(context, attrs, defstyleattr);          init(context, attrs, defstyleattr);          initpaint();      }        //设置切率      public void setlinesmoothness(float linesmoothness) {          if (linesmoothness != this.mlinesmoothness) {              this.mlinesmoothness = linesmoothness;          }      }        /**       * 初始化       */      private void initpaint() {          mxypaint = new paint();          mxypaint.setantialias(true);          mxypaint.setstrokewidth(xylinewidth);          mxypaint.setstrokejoin(paint.join.round);          mxypaint.setcolor(xylinecolor);            mxytextpaint = new paint();          mxytextpaint.setantialias(true);          mxytextpaint.settextsize(xytextsize);          mxytextpaint.setstrokejoin(paint.join.round);          mxytextpaint.setcolor(xytextcolor);          mxytextpaint.setstyle(paint.style.stroke);            mspinnerlinepaint = new paint();          mspinnerlinepaint.setantialias(true);          mspinnerlinepaint.setstrokewidth(xylinewidth);          mspinnerlinepaint.setcolor(linecolor);          mspinnerlinepaint.setstyle(paint.style.stroke);          mspinnerlinepaint.setstrokejoin(paint.join.round);      }        /**       * 初始化       *       * @param context       * @param attrs       * @param defstyleattr       */      private void init(context context, attributeset attrs, int defstyleattr) {          typedarray array = context.obtainstyledattributes(attrs, r.styleable.chartview, defstyleattr, 0);          int count = array.getindexcount();          for (int i = 0; i < count; i++) {              int attr = array.getindex(i);              if (attr == r.styleable.chartview_xy_line_color) {                  xylinecolor = array.getcolor(attr, xylinecolor);                } else if (attr == r.styleable.chartview_xy_line_width) {                  xylinewidth = (int) array.getdimension(attr, typedvalue.applydimension(typedvalue.complex_unit_px, xylinewidth, getresources().getdisplaymetrics()));                } else if (attr == r.styleable.chartview_xy_text_color) {                  xytextcolor = array.getcolor(attr, xytextcolor);                } else if (attr == r.styleable.chartview_xy_text_size) {                  xytextsize = (int) array.getdimension(attr, typedvalue.applydimension(typedvalue.complex_unit_px, xytextsize, getresources().getdisplaymetrics()));                } else if (attr == r.styleable.chartview_line_color) {                  linecolor = array.getcolor(attr, linecolor);                } else if (attr == r.styleable.chartview_interval) {                  interval = (int) array.getdimension(attr, typedvalue.applydimension(typedvalue.complex_unit_px, interval, getresources().getdisplaymetrics()));                } else if (attr == r.styleable.chartview_bg_color) {                  bgcolor = array.getcolor(attr, bgcolor);                } else if (attr == r.styleable.chartview_select_circle_color) {                  selectcirclecolor = array.getcolor(attr, selectcirclecolor);                } else if (attr == r.styleable.chartview_select_reminder_color) {                  selectremindercolor = array.getcolor(attr, selectremindercolor);                } else if (attr == r.styleable.chartview_isscroll) {                  isscroll = array.getboolean(attr, isscroll);              } else if (attr == r.styleable.chartview_show_position) {                  mshowpositiontype = array.getint(attr, mshowpositiontype);              }          }          array.recycle();      }        @override      protected void onlayout(boolean changed, int left, int top, int right, int bottom) {          if (changed) {              width = getwidth();              height = getheight();              //y轴文本的最大宽度              float textywdith = gettextbounds(mydata.get(getlistitemmaxindex(mydata)) + "", mxytextpaint).width();              for (int i = 0; i < mydata.size(); i++) {//求取y轴文本最大的宽度                  float temp = gettextbounds(mydata.get(i) + "", mxytextpaint).width();                  if (temp > textywdith)                      textywdith = temp;              }              int dp2 = dptopx(2);              int dp3 = dptopx(3);              mxori = (int) (dp2 + textywdith + dp2 + xylinewidth);              //获取x轴的最长文本的宽度所占的矩形              xvaluerect = gettextbounds(mxdata.get(getlistitemmaxindex(mxdata)), mxytextpaint);              //x轴文本高度              float textxheight = xvaluerect.height();              for (int i = 0; i < mxdata.size(); i++) {                  rect rect = gettextbounds(mxdata.get(i) + "", mxytextpaint);                  if (rect.height() > textxheight)                      textxheight = rect.height();                  if (rect.width() > xvaluerect.width())                      xvaluerect = rect;              }              myori = (int) (height - dp2 - textxheight - dp3 - xylinewidth);              mxinit = mxori + xvaluerect.width() / 2 + dptopx(5);              minxinit = width - (width - mxori) * 0.1f - interval * (mxdata.size() - 1);              maxxinit = mxinit;          }          selectindex = getselectindexfromshowtype(mshowpositiontype);          super.onlayout(changed, left, top, right, bottom);      }        @override      protected void ondraw(canvas canvas) {          canvas.drawcolor(bgcolor);          drawxy(canvas);          drawbrokenlineandpoint(canvas);      }        /**       * 绘制交点处对应的点       */      private void drawbrokenlineandpoint(canvas canvas) {          if (mxdata.size() <= 0)              return;          int layerid = canvas.savelayer(0, 0, width, height, null, canvas.all_save_flag);          drawbrokenline(canvas);          drawbrokenpoint(canvas);          // 将超出x轴坐标的部分截掉          mspinnerlinepaint.setstyle(paint.style.fill);          mspinnerlinepaint.setcolor(bgcolor);          mspinnerlinepaint.setxfermode(new porterduffxfermode(porterduff.mode.clear));          rectf rectf = new rectf(0, 0, mxori, height);          canvas.drawrect(rectf, mspinnerlinepaint);          mspinnerlinepaint.setxfermode(null);            canvas.restoretocount(layerid);      }        /**       * 绘制曲线对应的点       */      private void drawbrokenpoint(canvas canvas) {          float dp2 = dptopx(2);          float dp4 = dptopx(4);          float dp7 = dptopx(7);          log.e("selectindex", "index:" + selectindex);          //绘制节点          for (int i = 0; i < mxdata.size(); i++) {              float x = mxinit + interval * i;              float y = myori - myori * (1 - 0.1f) * mspinnervalue.get(mxdata.get(i)) / mydata.get(mydata.size() - 1);              //绘制选中点              if (i == selectindex - 1) {                  mspinnerlinepaint.setstyle(paint.style.fill);                  //设置选中颜色                  mspinnerlinepaint.setcolor(selectcirclecolor);                  canvas.drawcircle(x, y, dp7, mspinnerlinepaint);                  mspinnerlinepaint.setcolor(selectremindercolor);                  canvas.drawcircle(x, y, dp4, mspinnerlinepaint);                  drawfloattextbox(canvas, x, y - dp7, mspinnervalue.get(mxdata.get(i)));              }              //绘制普通节点              mspinnerlinepaint.setstyle(paint.style.fill);              mspinnerlinepaint.setcolor(color.white);              canvas.drawcircle(x, y, dp2, mspinnerlinepaint);              mspinnerlinepaint.setstyle(paint.style.stroke);              mspinnerlinepaint.setcolor(linecolor);              canvas.drawcircle(x, y, dp2, mspinnerlinepaint);            }      }        /**       * 绘制浮动框       * */      private void drawfloattextbox(canvas canvas, float x, float y, int text) {          int dp6 = dptopx(6);          int dp18 = dptopx(18);          //p1          path path = new path();          path.moveto(x, y);          //p2          path.lineto(x - dp6, y - dp6);          //p3          path.lineto(x - dp18, y - dp6);          //p4          path.lineto(x - dp18, y - dp6 - dp18);          //p5          path.lineto(x + dp18, y - dp6 - dp18);          //p6          path.lineto(x + dp18, y - dp6);          //p7          path.lineto(x + dp6, y - dp6);          //p1          path.lineto(x, y);          canvas.drawpath(path, mspinnerlinepaint);          mspinnerlinepaint.setcolor(color.white);          mspinnerlinepaint.settextsize(sptopx(14));          rect rect = gettextbounds(text + "", mspinnerlinepaint);          canvas.drawtext(text + "", x - rect.width() / 2, y - dp6 - (dp18 - rect.height()) / 2, mspinnerlinepaint);      }        /**       * 绘制平滑曲线       */      private void drawbrokenline(canvas canvas) {          mspinnerlinepaint.setstyle(paint.style.stroke);          mspinnerlinepaint.setcolor(linecolor);          //绘制折线          path path = new path();          float prepreviouspointx = float.nan;          float prepreviouspointy = float.nan;          float previouspointx = float.nan;          float previouspointy = float.nan;          float currentpointx = float.nan;          float currentpointy = float.nan;          float nextpointx;          float nextpointy;          int linesize = mxdata.size();          for (int i = 0; i < linesize; i++) {              float x;              float y;              if (float.isnan(currentpointx)) {                  currentpointx = getspinnerpoint(i).x;                  currentpointy = getspinnerpoint(i).y;              }              if (float.isnan(previouspointx)) {                  //是第一个点?                  if (i > 0) {                      previouspointx = getspinnerpoint(i - 1).x;                      previouspointy = getspinnerpoint(i - 1).y;                  } else {                      //用当前点表示上一个点                      previouspointx = currentpointx;                      previouspointy = currentpointy;                  }              }                if (float.isnan(prepreviouspointx)) {                  //是前两个点?                  if (i > 1) {                      prepreviouspointx = getspinnerpoint(i - 2).x;                      prepreviouspointy = getspinnerpoint(i - 2).y;                  } else {                      //当前点表示上上个点                      prepreviouspointx = previouspointx;                      prepreviouspointy = previouspointy;                  }              }                // 判断是不是最后一个点了              if (i < linesize - 1) {                  nextpointx = getspinnerpoint(i + 1).x;                  nextpointy = getspinnerpoint(i + 1).y;              } else {                  //用当前点表示下一个点                  nextpointx = currentpointx;                  nextpointy = currentpointy;              }                if (i == 0) {                  // 将path移动到开始点                  path.moveto(currentpointx, currentpointy);              } else {                  // 求出控制点坐标                  final float firstdiffx = (currentpointx - prepreviouspointx);                  final float firstdiffy = (currentpointy - prepreviouspointy);                  final float seconddiffx = (nextpointx - previouspointx);                  final float seconddiffy = (nextpointy - previouspointy);                  final float firstcontrolpointx = previouspointx + (mlinesmoothness * firstdiffx);                  final float firstcontrolpointy = previouspointy + (mlinesmoothness * firstdiffy);                  final float secondcontrolpointx = currentpointx - (mlinesmoothness * seconddiffx);                  final float secondcontrolpointy = currentpointy - (mlinesmoothness * seconddiffy);                  //画出曲线                  path.cubicto(firstcontrolpointx, firstcontrolpointy, secondcontrolpointx, secondcontrolpointy,                          currentpointx, currentpointy);              }                // 更新              prepreviouspointx = previouspointx;              prepreviouspointy = previouspointy;              previouspointx = currentpointx;              previouspointy = currentpointy;              currentpointx = nextpointx;              currentpointy = nextpointy;          }          canvas.drawpath(path, mspinnerlinepaint);      }        /**       * 绘制xy坐标       */      private void drawxy(canvas canvas) {          int length = dptopx(5);//刻度的长度          //绘制y坐标          canvas.drawline(mxori - xylinewidth / 2, 0, mxori - xylinewidth / 2, myori, mxypaint);          //绘制箭头          mxypaint.setstyle(paint.style.stroke);          path path = new path();          path.moveto(mxori - xylinewidth / 2 - dptopx(5), dptopx(12));          path.lineto(mxori - xylinewidth / 2, xylinewidth / 2);          path.lineto(mxori - xylinewidth / 2 + dptopx(5), dptopx(12));          canvas.drawpath(path, mxypaint);          //绘制刻度          int ylength = (int) (myori * (1 - 0.1f) / (mydata.size() - 1));//y轴上面空出10%,计算出y轴刻度间距          for (int i = 0; i < mydata.size(); i++) {              //绘制刻度              canvas.drawline(mxori, myori - ylength * i + xylinewidth / 2, mxori + length, myori - ylength * i + xylinewidth / 2, mxypaint);              mxytextpaint.setcolor(xytextcolor);              //绘制文本              string text = mydata.get(i) + "";              rect rect = gettextbounds(text, mxytextpaint);              canvas.drawtext(text, 0, text.length(), mxori - xylinewidth - dptopx(2) - rect.width(), myori - ylength * i + rect.height() / 2, mxytextpaint);          }          //绘制坐标          canvas.drawline(mxori, myori + xylinewidth / 2, width, myori + xylinewidth / 2, mxypaint);          //绘制箭头          mxypaint.setstyle(paint.style.stroke);          path = new path();          //整个长度          float xlength = mxinit + interval * (mxdata.size() - 1) + (width - mxori) * 0.1f;          if (xlength < width)              xlength = width;          path.moveto(xlength - dptopx(12), myori + xylinewidth / 2 - dptopx(5));          path.lineto(xlength - xylinewidth / 2, myori + xylinewidth / 2);          path.lineto(xlength - dptopx(12), myori + xylinewidth / 2 + dptopx(5));          canvas.drawpath(path, mxypaint);          //绘制x轴刻度          for (int i = 0; i < mxdata.size(); i++) {              float x = mxinit + interval * i;              if (x >= mxori) {//只绘制从原点开始的区域                  mxytextpaint.setcolor(xytextcolor);                  canvas.drawline(x, myori, x, myori - length, mxypaint);                  //绘制x轴文本                  string text = mxdata.get(i);                  rect rect = gettextbounds(text, mxytextpaint);                  if (i == selectindex - 1) {                      mxytextpaint.setcolor(linecolor);                      canvas.drawtext(text, 0, text.length(), x - rect.width() / 2, myori + xylinewidth + dptopx(2) + rect.height(), mxytextpaint);                      canvas.drawroundrect(x - xvaluerect.width() / 2 - dptopx(3), myori + xylinewidth + dptopx(1), x + xvaluerect.width() / 2 + dptopx(3), myori + xylinewidth + dptopx(2) + xvaluerect.height() + dptopx(2), dptopx(2), dptopx(2), mxytextpaint);                  } else {                      canvas.drawtext(text, 0, text.length(), x - rect.width() / 2, myori + xylinewidth + dptopx(2) + rect.height(), mxytextpaint);                  }              }          }      }        private float startx;      private float startx;        @override      public boolean ontouchevent(motionevent event) {          if (isscrolling)              return super.ontouchevent(event);              //当该view获得点击事件,就请求父控件不拦截事件          this.getparent().requestdisallowintercepttouchevent(true);          obtainvelocitytracker(event);          switch (event.getaction()) {              case motionevent.action_down:                  startx = event.getx();                  startx = event.getx();                  log.e("xxxx", "down:" + startx + "");                  break;              case motionevent.action_move:                  //滑动距离小于等于8的时候任务为短距离滑动                  //当前x轴的尺寸与设置的x轴间隔的距离之乘积大于 屏幕中的显示布局宽度与x轴七点之差时,开始移动                  if (interval * mxdata.size() > width - mxori) {                      //获取滑动的距离                      float dis = event.getx() - startx;                      //重新赋值给startx                      startx = event.getx();                      //当前x原点距离与左右滑动的距离之和没有最小值大,则将当前x距离赋值为最小,以下相似                      if (mxinit + dis < minxinit) {                          mxinit = minxinit;                      } else if (mxinit + dis > maxxinit) {                          mxinit = maxxinit;                      } else {                          mxinit = mxinit + dis;                      }                      invalidate();                  }                  break;              case motionevent.action_up:                  isshortslide = math.abs(event.getx() - startx) <= dptopx(8);                  clickaction(event);                  scrollafteractionup();                  this.getparent().requestdisallowintercepttouchevent(false);                  recyclevelocitytracker();                  break;              case motionevent.action_cancel:                  //增加这行代码防止与父类的滑动事件冲突                  this.getparent().requestdisallowintercepttouchevent(false);                  recyclevelocitytracker();                  break;          }          return true;      }        //是否正在滑动      private boolean isscrolling = false;        /**       * 手指抬起后的滑动处理       */      private void scrollafteractionup() {          if (!isscroll)              return;          final float velocity = getvelocity();          float scrolllength = maxxinit - minxinit;          if (math.abs(velocity) < 10000)              scrolllength = (maxxinit - minxinit) * math.abs(velocity) / 10000;          valueanimator animator = valueanimator.offloat(0, scrolllength);          animator.setduration((long) (scrolllength / (maxxinit - minxinit) * 1000));//时间最大为1000毫秒,此处使用比例进行换算          animator.setinterpolator(new decelerateinterpolator());          animator.addupdatelistener(new valueanimator.animatorupdatelistener() {              @override              public void onanimationupdate(valueanimator valueanimator) {                  float value = (float) valueanimator.getanimatedvalue();                  if (velocity < 0 && mxinit > minxinit) {//向左滑动                      if (mxinit - value <= minxinit)                          mxinit = minxinit;                      else                          mxinit = mxinit - value;                  } else if (velocity > 0 && mxinit < maxxinit) {//向右滑动                      if (mxinit + value >= maxxinit)                          mxinit = maxxinit;                      else                          mxinit = mxinit + value;                  }                  invalidate();              }          });          animator.addlistener(new animator.animatorlistener() {              @override              public void onanimationstart(animator animator) {                  isscrolling = true;              }                @override              public void onanimationend(animator animator) {                  isscrolling = false;              }                @override              public void onanimationcancel(animator animator) {                  isscrolling = false;              }                @override              public void onanimationrepeat(animator animator) {                }          });          animator.start();        }        /**       * 获取速度       *       * @return       */      private float getvelocity() {          if (mtracker != null) {              mtracker.computecurrentvelocity(1000);              return mtracker.getxvelocity();          }          return 0;      }        /**       * 点击x轴坐标或者折线节点       *  */      // 44  142  139      private void clickaction(motionevent event) {          int dp8 = dptopx(8);          float eventx = event.getx();          float eventy = event.gety();          if (!isshortslide) {              for (int i = 0; i < mxdata.size(); i++) {                  float x = mxinit + interval * i;                  float start = mxori;                  if (x >= start + (mselectmiddle - 1) * interval && x < start + mselectmiddle * interval) {                      selectindex = i + 1;                      invalidate();                  }              }              return;          }          for (int i = 0; i < mxdata.size(); i++) {              //节点              float x = mxinit + interval * i;              float y = myori - myori * (1 - 0.1f) * mspinnervalue.get(mxdata.get(i)) / mydata.get(mydata.size() - 1);              if (eventx >= x - dp8 && eventx <= x + dp8 &&                      eventy >= y - dp8 && eventy <= y + dp8 && selectindex != i + 1) {//每个节点周围范围内都是可点击区域                  selectindex = i + 1;                  invalidate();                  return;              }              //x轴刻度              string text = mxdata.get(i);              rect rect = gettextbounds(text, mxytextpaint);              x = mxinit + interval * i;              y = myori + xylinewidth + dptopx(2);              if (eventx >= x - rect.width() / 2 - dp8 && eventx <= x + rect.width() + dp8 / 2 &&                      eventy >= y - dp8 && eventy <= y + rect.height() + dp8 && selectindex != i + 1) {                  selectindex = i + 1;                  invalidate();                  return;              }          }      }          /**       * 获取速度跟踪器       *       * @param event       */      private void obtainvelocitytracker(motionevent event) {          if (!isscroll)              return;          if (mtracker == null) {              mtracker = velocitytracker.obtain();          }          mtracker.addmovement(event);      }        /**       * 回收速度跟踪器       */      private void recyclevelocitytracker() {          if (mtracker != null) {              mtracker.recycle();              mtracker = null;          }      }        /**       * 根据用户输入显示类型,在滑动时在不同的位置显示提示框       */      private int getselectindexfromshowtype(int showpositiontype) {          int visiblescale = (width - mxori) / interval;          switch (showpositiontype) {              case first:                  mselectmiddle = 1;                  return mselectmiddle;              case middle:                  if (mxdata.size() <= visiblescale) {                      mselectmiddle = middleindex(mxdata.size());                  } else {                      mselectmiddle = middleindex(visiblescale);                  }                  return mselectmiddle;  //屏幕可显示的刻度              case end:                  if (mxdata.size() <= visiblescale) {                      mselectmiddle = mxdata.size();                  } else {                      mselectmiddle = visiblescale;                  }                  return visiblescale;              default:                  mselectmiddle = 0;                  return mselectmiddle;          }      }        public void setvalue(map<string, integer> value) {          this.mspinnervalue = value;          invalidate();      }        public void setvalue(map<string, integer> value, list<string> xvalue, list<integer> yvalue) {          this.mspinnervalue = value;          this.mxdata = xvalue;          this.mydata = yvalue;          invalidate();      }          public map<string, integer> getvalue() {          return mspinnervalue;      }        /**       * 获取丈量文本的矩形       *       * @param text       * @param paint       * @return       */      private rect gettextbounds(string text, paint paint) {          rect rect = new rect();          paint.gettextbounds(text, 0, text.length(), rect);          return rect;      }        /**       * dp转化成为px       *       * @param dp       * @return       */      private int dptopx(int dp) {          float density = getcontext().getresources().getdisplaymetrics().density;          return (int) (dp * density + 0.5f * (dp >= 0 ? 1 : -1));      }        /**       * sp转化为px       *       * @param sp       * @return       */      private int sptopx(int sp) {          float scaleddensity = getcontext().getresources().getdisplaymetrics().scaleddensity;          return (int) (scaleddensity * sp + 0.5f * (sp >= 0 ? 1 : -1));      }        /**       * 获取集合中最长的index       */      private static final int null_index = -1;        public int getlistitemmaxindex(list<?> data) {          if (data == null || data.size() < 1) {              return null_index;          }          int max = (data.get(0) + "").length();          for (int i = 0; i < data.size(); i++) {              string s = data.get(i) + "";              if (s.length() > max) {                  return i;              }          }          return null_index;      }        //获得在滑动结束的时候在屏幕内的点      private int middleindex(int size) {          if (size % 2 == 0) {              return size / 2;          } else {              return size / 2 + 1;          }      }          /**       * 根据两点坐标获取中间某个点       *       * @param from 坐标1       * @param to   坐标2       */        //获取已知点的斜率 y = kx+b      private float getslope(point from, point to) {          float k = (to.y - from.y) / (to.x - from.x);          log.e("point", "参数b:" + k);          return k;      }        //获取参数 b      private float getparams(point from, point to) {          float b = from.y - (getslope(from, to) * from.x);          log.e("point", "参数b:" + b);          return b;      }        //根据两点间的坐标获取x轴的任意一个坐标x值,      private float getarbitrarilyx(point from, point to, int grade, int needgrade) {          //获得输入的新坐标          float x = ((to.x - from.x) * needgrade) / grade + from.x;          log.e("point", "x坐标值:" + x);          return x;      }        //获取坐标值      private point getpoint(point from, point to, int grade, int needgrade) {          point point = new point();          point.setx(getarbitrarilyx(from, to, grade, needgrade));          float slope = getslope(from, to);          point.sety(slope * point.x + getparams(from, to));          return point;      }        //获取绘制折线的点      private point getspinnerpoint(int valueindex) {          float x = mxinit + interval * (valueindex);          float y = myori - myori * (1 - 0.1f) * mspinnervalue.get(mxdata.get(valueindex)) / mydata.get(mydata.size() - 1);          return new point(x, y);      }        private class point {          float x;          float y;            public point() {          }            public float getx() {              return x;          }            public void setx(float x) {              this.x = x;          }            public float gety() {              return y;          }            public void sety(float y) {              this.y = y;          }            public point(float x, float y) {              this.x = x;              this.y = y;          }            @override          public string tostring() {              return "point{" +                      "x=" + x +                      ", y=" + y +                      '}';          }      }  }

以上就是android开发分享android实现可以滑动的平滑曲线图的全部内容,希望对大家的学习有所帮助,也希望大家多多支持<计算机技术网(www.ctvol.com)!!>。

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/addevelopment/1111630.html

(0)
上一篇 2022年7月1日
下一篇 2022年7月1日

精彩推荐