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