公司需求需要在每一段做暂停和播放 还有每一段时间不一样 ,所以不能整段用一个path和一个动画 ,那样时间就会根据整段的长度来平均总时间, 长度可以通过
pathMeasure = new PathMeasure();
mMovePath.lineTo(pointX[1], pointY[1]); pathMeasure.setPath(mMovePath, false);
mLenght = (int) pathMeasure.getLength();
注意setpath第二个参数如果设置为true那么最后的长度 会有包含从终点到原点的直线距离
为了解决每一段能够实现不一样的时间走完 ,设置完第一段path后判断最后的点是否和下一段的起始点相似(差不多+-1px 因为不同分辨率的dip不相同则会导致可能有小数点)
public class SportLine extends View { private Paint mPaintBezier,mPaintrender; Paint mPaint; private Path mMovePath; private Path renderPath; Path AllPath; private PathMeasure pathMeasure; //path路径的总长度 private int mLenght; //当前路径的长度 private int mCurrentPath; private float[] currentPosition; private Bitmap bitmap; int len01; int len02; int len03; int len04; int len05; int time01=5000; int time02=5000; int time03=5000; int time04=5000; int lentype=1; private float pointX[] = new float[6]; private float pointY[] = new float[6]; float pointXBezier[]=new float[4]; float pointYBezier[]=new float[4]; boolean isFirst =true; boolean issecond =true; boolean isThree =true; boolean isFourth =true; boolean isFifth =true; public SportLine(Context context) { super(context); } public SportLine(Context context, AttributeSet attrs) { super(context, attrs); currentPosition = new float[2]; bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.sport_goingicon); mPaint=new Paint(); //初始化画笔 mPaintBezier=new Paint(Paint.ANTI_ALIAS_FLAG); mPaintBezier.setStrokeWidth(DeviceUtils.getdimen2px(getContext(),R.dimen.dp_12)); // int colorStart = getResources().getColor(R.color.colorPrimary); // int color1 = Color.GRAY; // int colorEnd = getResources().getColor(R.color.colorAccent); // LinearGradient backGradient = new LinearGradient(0, 0, 0, 10, new int[]{colorStart, color1 ,colorEnd}, null, Shader.TileMode.CLAMP); // mPaintBezier.setShader(backGradient); mPaintBezier.setStyle(Paint.Style.STROKE); mPaintBezier.setColor(getResources().getColor(R.color.sport_linebgcolor)); mPaintBezier.setStrokeJoin(Paint.Join.ROUND); //线条结束处绘制一个半圆 mPaintBezier.setStrokeCap(Paint.Cap.ROUND); // mPaintCircle=new Paint(Paint.ANTI_ALIAS_FLAG); // mPaintCircle.setStrokeWidth(8); // mPaintCircle.setStyle(Paint.Style.FILL_AND_STROKE); // mPaintCircle.setColor(Color.BLUE); // setOnClickListener(this); mPaintrender=new Paint(Paint.ANTI_ALIAS_FLAG); mPaintrender.setStrokeWidth(DeviceUtils.getdimen2px(getContext(),R.dimen.dp_12)); mPaintrender.setStyle(Paint.Style.STROKE); mPaintrender.setColor(getResources().getColor(R.color.sport_linecolor)); mPaintrender.setStrokeJoin(Paint.Join.ROUND); mPaintrender.setStrokeCap(Paint.Cap.ROUND); Log.i(Constants.XQLOG,"dp_224="+DeviceUtils.getdimen2px(getContext(),R.dimen.dp_224)+"dp_626="+DeviceUtils.getdimen2px(getContext(), R.dimen.dp_626)); pointX[0]=getdimen2px(getContext(), R.dimen.dp_40); pointY[0] = getdimen2px(getContext(), R.dimen.dp_626); pointX[1]=getdimen2px(getContext(), R.dimen.dp_224); pointY[1] = getdimen2px(getContext(), R.dimen.dp_626); pointX[2]=getdimen2px(getContext(), R.dimen.dp_410); pointY[2] = getdimen2px(getContext(), R.dimen.dp_140); pointX[3]=getdimen2px(getContext(), R.dimen.dp_595); pointY[3] = getdimen2px(getContext(), R.dimen.dp_140); pointX[4]=getdimen2px(getContext(), R.dimen.dp_780); pointY[4] = getdimen2px(getContext(), R.dimen.dp_626); pointX[5]=getdimen2px(getContext(), R.dimen.dp_964); pointY[5] = getdimen2px(getContext(), R.dimen.dp_626); // pointX[1]=getdimen2px(getContext(), R.dimen.dp_224); // pointY[1] = getdimen2px(getContext(), R.dimen.dp_626); // // pointX[2]=getdimen2px(getContext(), R.dimen.dp_410); // pointY[2] = getdimen2px(getContext(), R.dimen.dp_140); pointXBezier[0]=getdimen2px(getContext(), R.dimen.dp_234); pointYBezier[0]=getdimen2px(getContext(), R.dimen.dp_560); pointXBezier[1]=getdimen2px(getContext(), R.dimen.dp_375); pointYBezier[1]=getdimen2px(getContext(), R.dimen.dp_144); // pointX[3]=getdimen2px(getContext(), R.dimen.dp_595); // pointY[3] = getdimen2px(getContext(), R.dimen.dp_140); // // pointX[4]=getdimen2px(getContext(), R.dimen.dp_780); // pointY[4] = getdimen2px(getContext(), R.dimen.dp_626); pointXBezier[2]=getdimen2px(getContext(), R.dimen.dp_630); pointYBezier[2]=getdimen2px(getContext(), R.dimen.dp_146); pointXBezier[3]=getdimen2px(getContext(), R.dimen.dp_770); pointYBezier[3]=getdimen2px(getContext(), R.dimen.dp_540); renderPath =new Path(); renderPath.moveTo(pointX[0],pointY[0]); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mMovePath=new Path(); AllPath=new Path(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //画圆 //canvas.drawCircle(mCircleX,mCircleY,30,mPaintCircle); //给Path设置贝塞尔曲线,然后canvas画 mMovePath.reset(); AllPath.reset(); // mMovePath.moveTo(mStartPointX,mStartPointY); /** * quadTo()绘制二阶贝塞尔曲线 * cubicTo()绘制三阶贝塞尔曲线 */ // mMovePath.lineTo(mStartPointX,mStartPointY); // mMovePath.quadTo(mFlagPointX,mFlagPointY,mEndPointX-300,mEndPointY-100); // mMovePath.lineTo(mEndPointX-50,mEndPointY-100); // mMovePath.quadTo(mFlagPointX+50,mFlagPointY,mEndPointX,mEndPointY); //mMovePath.moveTo(100,200); //mMovePath.lineTo(150,200); // mMovePath.cubicTo(214,34, // 220,26, // 240,20); AllPath.moveTo(pointX[0], pointY[0]); AllPath.lineTo(pointX[1], pointY[1]); AllPath.cubicTo( pointXBezier[0], pointYBezier[0], pointXBezier[1], pointYBezier[1], pointX[2], pointY[2]); AllPath.quadTo( pointX[2], pointY[2], pointX[3], pointY[3]); AllPath.cubicTo( pointXBezier[2],pointYBezier[2], pointXBezier[3],pointYBezier[3], pointX[4], pointY[4]); AllPath.lineTo( pointX[5], pointY[5]); Log.i(Constants.XQLOG,"heigh:"+ getdimen2px(getContext(), R.dimen.dp_595)); mLenght=0; pathMeasure = new PathMeasure(); if(lentype==1) { mMovePath.moveTo(pointX[0], pointY[0]); // pathMeasure.setPath(mMovePath,true); // mLenght = (int) pathMeasure.getLength(); mMovePath.lineTo(pointX[1], pointY[1]); pathMeasure.setPath(mMovePath, false); len01 = (int) pathMeasure.getLength() - mLenght; mLenght = (int) pathMeasure.getLength();//244 // mLenght=244; Log.i(Constants.XQLOG, "len01=" + len01); } if(lentype==2){ mMovePath.moveTo(pointX[1], pointY[1]); mMovePath.cubicTo( pointXBezier[0], pointYBezier[0], pointXBezier[1], pointYBezier[1], pointX[2], pointY[2]); pathMeasure.setPath(mMovePath,false); len02 = (int) pathMeasure.getLength()-mLenght; mLenght = (int) pathMeasure.getLength();//878 Log.i(Constants.XQLOG,"len02="+len02); } if(lentype==3){ mMovePath.moveTo(pointX[2], pointY[2]); mMovePath.quadTo( pointX[2], pointY[2], pointX[3], pointY[3]); pathMeasure.setPath(mMovePath,false); len03 = (int) pathMeasure.getLength()-mLenght; mLenght = (int) pathMeasure.getLength();//1085 // //mMovePath.cubicTo(300,26,308,34,370,200); Log.i(Constants.XQLOG,"len03="+len03); } if(lentype==4){ mMovePath.moveTo(pointX[3], pointY[3]); mMovePath.cubicTo( pointXBezier[2], pointYBezier[2], pointXBezier[3], pointYBezier[3], pointX[4], pointY[4]); pathMeasure.setPath(mMovePath,false); len04 = (int) pathMeasure.getLength()-mLenght; mLenght = (int) pathMeasure.getLength();//2244 Log.i(Constants.XQLOG,"len04="+len04); } if(lentype==5){ mMovePath.moveTo( pointX[4], pointY[4]); mMovePath.lineTo(pointX[5], pointY[5]); pathMeasure.setPath(mMovePath,false); len05 = (int) pathMeasure.getLength()-mLenght; mLenght = (int) pathMeasure.getLength();//1167 Log.i(Constants.XQLOG,"len05="+len05); } if(lentype==1){ mLenght=len01; } // else if(lentype==2){ Log.i(Constants.XQLOG,"lentype="+2); //当第一段path过后重新设置点和启动动画算时间 这个时候如何判断第二个点的启动 只能接近 不可能等于 if(issecond&&(mCurrentPath <len01||mCurrentPath ==len01)&&((int)(currentPosition[0])== pointX[1]||((int)(currentPosition[0])== pointX[1]-1)) && ((int)(currentPosition[1])== pointY[1]||((int)(currentPosition[1])== pointY[1]-1))) { issecond=false; mLenght=len02; valueAnimator.cancel(); valueAnimator=null; time=time01; startAnimator(); // } } if(isThree&&(mCurrentPath <len02||mCurrentPath ==len02)&&((int)(currentPosition[0])== pointX[2]||((int)(currentPosition[0])== pointX[2]-1)) && ((int)(currentPosition[1])== pointY[2]||((int)(currentPosition[1])== pointY[2]-1))) { isThree=false; mLenght=len03; valueAnimator.cancel(); valueAnimator=null; time=time02; startAnimator(); // } } if(isFourth&&(mCurrentPath <len03||mCurrentPath ==len03)&& ((int)(currentPosition[0])== pointX[3]||((int)(currentPosition[0])== pointX[3]-1)) && ((int)(currentPosition[1])== pointY[3]||((int)(currentPosition[1])== pointY[3]-1))){ isFourth =false; mLenght=len04; time=time03; valueAnimator.cancel(); valueAnimator=null; startAnimator(); } if(isFifth&&(mCurrentPath <len04||mCurrentPath ==len04)&&((int)(currentPosition[0])== pointX[4]||((int)(currentPosition[0])== pointX[4]-1)) && ((int)(currentPosition[1])==pointY[4]||((int)(currentPosition[1])==pointY[4]-1))){ isFifth =false; mLenght=len05; time=time04; valueAnimator.cancel(); valueAnimator=null; startAnimator(); } // mMovePath.quadTo(190,70,220,20); // mMovePath.lineTo(200,50); // mMovePath.quadTo(220,70,270,100); canvas.drawPath(mMovePath,mPaintBezier); canvas.drawPath(AllPath,mPaintBezier); canvas.drawPath(renderPath,mPaintrender); if(mCurrentPath == 0 && currentPosition[0]==0 && currentPosition[1]==0){ startAnimator(); }else { Log.i(Constants.XQLOG,"bitmap currentPosition[0]="+currentPosition[0]+"bitmap currentPosition[1]="+currentPosition[1]); canvas.drawBitmap(bitmap, currentPosition[0] - bitmap.getWidth() / 2, currentPosition[1] - bitmap.getHeight() / 2, mPaint); } } int time =5000; ValueAnimator valueAnimator; private void startAnimator(){ valueAnimator = ValueAnimator.ofInt(0, mLenght); valueAnimator.setDuration(time); // valueAnimator.setRepeatCount(0); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { mCurrentPath = (int) animation.getAnimatedValue(); pathMeasure.getPosTan(mCurrentPath, currentPosition, null); renderPath.lineTo(currentPosition[0],currentPosition[1]); Log.i(Constants.XQLOG,"mCurrentPath="+mCurrentPath+"currentPosition[0]="+currentPosition[0]+"currentPosition[1]="+currentPosition[1]); if(((int)(currentPosition[0])== pointX[1]||((int)(currentPosition[0])== pointX[1]-1)) && ((int)(currentPosition[1])== pointY[1]||((int)(currentPosition[1])== pointY[1]-1))){ lentype=2; // valueAnimator.cancel(); // valueAnimator=null; } if(((int)(currentPosition[0])== pointX[2]||((int)(currentPosition[0])== pointX[2]-1)) && ((int)(currentPosition[1])== pointY[2]||((int)(currentPosition[1])== pointY[2]-1))) { lentype=3; // valueAnimator.cancel(); // valueAnimator=null; } if(((int)(currentPosition[0])== pointX[3]||((int)(currentPosition[0])== pointX[3]-1)) && ((int)(currentPosition[1])== pointY[3]||((int)(currentPosition[1])== pointY[3]-1))){ lentype=4; } if(((int)(currentPosition[0])== pointX[4]||((int)(currentPosition[0])== pointX[4]-1)) && ((int)(currentPosition[1])== pointY[4]||((int)(currentPosition[1])== pointY[4]-1))){ lentype=5; } invalidate(); } }); valueAnimator.start(); } public void startRun(){ valueAnimator.resume(); } public void stopRun(){ valueAnimator.pause(); } public void setTime(int time ,int time01,int time02,int time03,int time04){ this.time =time; this.time01 =time01; this.time02 =time02; this.time03 =time03; this.time04 =time04; } }