志在指尖
用双手敲打未来

途径跟踪 PathMeasure的简单运用

平常用path画一些简略的几何图形,出现的时分也是现已制作好的图形,想想,如果像动画相同看到它的制作轨道,是不是更酷?今日介绍的这个类PathMeasure便是干这个的,知道它的存在仍是由于看了启舰写的的自定义控件那本书。好,进入正题。
先说说Path,当你设置画笔是描边形式时,你制作的Path能够看做一条条连续不断的线段首尾相连。当你设置画笔是填充形式时,你制作一个起点和结尾,path是制作不出来的(除非你制作3个点)。所以在运用途径跟踪的条件,先把画笔设为描边形式,由于画笔默许的款式是填充形式,这是第一个注意事项。在运用PathMeasure时,对它的理解越简略通透,你就会知道,用它需要准备哪些变量,变量悉数初始完毕,用起来就像照葫芦画瓢相同简略!
PathMeasure和一个你制作好的完好path绑定,然后,你能够随意设置起点和结尾,得到两点之间的path,得到这个path怎样用呢,你是不是会这么想:我有一条线段,分红10等份,我每次更正起点和结尾,取0-1,1-2,2-3…这些片段途径来制作!不用那么麻烦的,你能够直接把起点固定为0,逐步批改结尾,这样你会得到0-1,0-2,0-3…的path。然后交给canvas去制作就行了,由于canvas在3个10毫秒分别制作0-1,0-2,0-3,它看起来便是30毫秒内从0-3的完好轨道。这个进程就类似scrollTo。接下来,看看常用的3个办法:
publicPathMeasure(Pathpath,booleanforceClosed){//Thenativeimplementationdoesnotcopythepath,preventitfrombeingGC’dmPath=path;
native_instance=native_create(path!=null?path.readOnlyNI():0,
forceClosed);
}
1.第一个参数便是你要跟踪的path,第二个参数强制关闭,表明是否把你传入的第一个path作为全封闭途径处理。举个比如:
假设pathMeasure传的第一个path,是用3条线段制作的,如左图,每段长为50px,那么pathMeasure结构办法的forceClose为true时,它把你的传入的path作为全封闭途径处理,也便是最初第二张图,这时pathMeasure.genLength()获取的途径便是50*4;如果forceClose设为false,那么它仍是作为path原始的途径,该几条线就几条线,pathMeasure获取的途径长便是50*3。所以,主张结构的pathMeasure,直接设为false,保持原始途径的容貌。
第二个办法便是最常用的截取一段path的办法:
publicbooleangetSegment(floatstartD,floatstopD,Pathdst,booleanstartWithMoveTo)
前两个参数一望而知,不多介绍,有意思的是后边两位。第3个dst,便是用来接收截取完之后的desPath,第4个参数的true和false,将直接影响desPath。考虑一下这种状况,假设desPath初始化时就现已添加了一段途径,如(0,0)到(50,50),这是一条斜线。那么之后getSegment办法走完,desPath新增的截取path的起点和结尾分别为(100,0)和(100,100),新path怎样个添加法呢?这便是startWithMoveTo()这个办法决定的,它为true:好,制作完(0,0)到(50,50)之后,体系帮你调一次moveTo(x,y),制作起点直接挪到截取path的起点上,如左图。如果为false:制作完(0,0)到(50,50)之后,体系帮你调一次lineTo(x,y),把最开始的path尾巴和我新截取的path头给首尾相连,如右图。说的现已很详细了,再来张手绘图,应该一望而知了。
第3个办法很简略的,它的作用便是切换途径概括,假设我画了一个圆,我下一条途径在圆里面,可不是在圆周上,怎样办,调它就行了,此时你会发现pathMeasure.getLength()也会重置为你新途径概括的长度.
publicbooleannextContour()
办法讲完,实战写个看看。这儿我画的仍是从书里看的那个支付完成控件,由于我便是看懂了这个控件,才逐步能画出五角星,搜索框这样的图标。所以,我仍是乐意把启舰写的这个简略却又触及全面的比如再分享给大家。这儿上传的是静态图,实际上是动态的,自己写个demo能够看到制作进程。
publicclassAiliPayViewextendsView{privatePaintpaint;privatePathpath,desPath;privatePathMeasurepathMeasure;privateValueAnimatorvalueAnimator;privatefloatcurValue;privatebooleanisNext=false;publicAiliPayView(Contextcontext){super(context);
init();
}publicAiliPayView(Contextcontext,@NullableAttributeSetattrs){super(context,attrs);
init();
}publicAiliPayView(Contextcontext,@NullableAttributeSetattrs,intdefStyleAttr){super(context,attrs,defStyleAttr);
init();
}privatevoidinit(){
setLayerType(LAYER_TYPE_SOFTWARE,null);
paint=newPaint(Paint.ANTI_ALIAS_FLAG);
paint.setStrokeWidth(8);
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.BLACK);
path=newPath();
desPath=newPath();
}
@OverrideprotectedvoidonSizeChanged(intw,inth,intoldw,intoldh){super.onSizeChanged(w,h,oldw,oldh);
path.addCircle(w/2,h/2,w/2-4,Path.Direction.CW);
path.moveTo(w/4,h/2);
path.lineTo(w/2,h/4*3);
path.lineTo(w/4*3,h/4);
pathMeasure=newPathMeasure(path,false);
valueAnimator=ValueAnimator.ofFloat(0,2);
valueAnimator.addUpdateListener(newValueAnimator.AnimatorUpdateListener(){
@OverridepublicvoidonAnimationUpdate(ValueAnimatoranimation){
curValue=(float)animation.getAnimatedValue();
invalidate();
}
});
valueAnimator.setDuration(3000);
valueAnimator.start();
}
@OverrideprotectedvoidonDraw(Canvascanvas){super.onDraw(canvas);if(curValue<1){floatstop=pathMeasure.getLength()*curValue;
pathMeasure.getSegment(0,stop,desPath,true);
}else{if(!isNext){
isNext=true;//这儿是临界状态,getlength是圆的总长pathMeasure.getSegment(0,pathMeasure.getLength(),desPath,true);//途径概括切换pathMeasure.nextContour();
}else{//getlength是新概括的总长,还有true的设置,由于折线途径在圆里面,所以把制作起点更换,不然,折线的起点和圆又会连起来
floatstop=pathMeasure.getLength()*(curValue-1);
pathMeasure.getSegment(0,stop,desPath,true);
}
}
canvas.drawPath(desPath,paint);
}
}
代码中有些细节值得注意:
1.在获取中画圆时,圆心选取没什么问题,半径的设置或许需要根据长宽不一致,进一步的确认,我这儿默许长宽是持平的写法。另外,我设置的圆半径为w/2-4,为什么要减4呢?由于画笔的描边宽度我设置的是8,当我不减去画笔宽度的一半时,你能够发现最终的制作的圆于控件区域相切的4个点,都会显得细一点。你能够幻想,画笔的笔尖宽度为8,以它中点扫去,刚好一半的宽度超出的显示区域,所以,半径减去画笔一半的宽度。
2.从圆途径切换到折线途径,用isNext这个标识。由于咱们的值动画是匀速的,值区域在(0,2),能够确保监听值在<1时,控件还在画圆,那咱们能够认为监听值等于1,便是圆刚好完毕吗?其实是无法确保的,由于不断改变的curValue或许是从0.99直接到1.01,它不必定等于1的。所以咱们在curValue》=1的第一时间,咱们制作完好个圆途径,然后切换途径概括,pathMeasure.getLength()就从圆周长变成了折线的长度。这也是后来的getSegment()的结尾值(curValue-1)的原因。

未经允许不得转载:IT技术网站 » 途径跟踪 PathMeasure的简单运用
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!

 

志在指尖 用双手敲打未来

登录/注册IT技术大全

热门IT技术

C#基础入门   SQL server数据库   系统SEO学习教程   WordPress小技巧   WordPress插件   脚本与源码下载