Android使用自定义View绘制渐隐渐现动画
实现了一个有趣的小东西:使用自定义View绘图,一边画线,画出的线条渐渐变淡,直到消失。效果如下图所示:
用属性动画或者渐变填充(Shader)可以做到一笔一笔的变化,但要想一笔渐变(手指不抬起边画边渐隐),没在Android中找到现成的API可用。所以,自己做了一个。
基本的想法是这样的:
在View的onTouchEvent中记录触摸点,生成一条一条的线LineElement,放在一个List中。给每个LineElement配置一个Paint实例。
在onDraw中绘制线段。
变换LineElement的Paint实例的Alpha值。
根据Alpha值重组线段列表
别的不说了,上代码:
packagecom.example.disappearinglines; importandroid.content.Context; importandroid.graphics.Canvas; importandroid.graphics.Paint; importandroid.graphics.Path; importandroid.graphics.RectF; importandroid.os.Handler; importandroid.os.Message; importandroid.os.SystemClock; importandroid.support.annotation.NonNull; importandroid.util.AttributeSet; importandroid.util.Log; importandroid.view.MotionEvent; importandroid.view.View; importjava.util.ArrayList; importjava.util.Collection; importjava.util.Iterator; importjava.util.List; importjava.util.ListIterator; publicclassDisappearingDoodleViewextendsView{ finalstaticStringTAG="DoodleView"; classLineElement{ staticfinalpublicintALPHA_STEP=5; staticfinalpublicintSUBPATH_DIMENSION=8; publicLineElement(){ mPaint=newPaint(); mPaint.setARGB(255,255,0,0); mPaint.setAntiAlias(true); mPaint.setStrokeWidth(16); mPaint.setStrokeCap(Paint.Cap.BUTT); mPaint.setStyle(Paint.Style.STROKE); } publicLineElement(Paintpaint){ mPaint=paint; } publicvoidsetPaint(Paintpaint){ mPaint=paint; } publicvoidsetAlpha(intalpha){ mPaint.setAlpha(alpha); } publicfloatmStartX=-1; publicfloatmStartY=-1; publicfloatmEndX=-1; publicfloatmEndY=-1; publicPaintmPaint; } privateLineElementmCurrentLine=null; privateList<LineElement>mLines=null; privatelongmElapsed=0; privateHandlermHandler=newHandler(){ @Override publicvoidhandleMessage(Messagemsg){ DisappearingDoodleView.this.invalidate(); } }; publicDisappearingDoodleView(Contextcontext){ super(context); } publicDisappearingDoodleView(Contextcontext,AttributeSetattrs){ super(context,attrs); } @Override protectedvoidonDraw(Canvascanvas){ mElapsed=SystemClock.elapsedRealtime(); if(mLines!=null){ for(LineElemente:mLines){ if(e.mStartX<0||e.mEndY<0)continue; canvas.drawLine(e.mStartX,e.mStartY,e.mEndX,e.mEndY,e.mPaint); } compactPaths(); } } @Override publicbooleanonTouchEvent(MotionEventevent){ floatx=event.getX(); floaty=event.getY(); intaction=event.getAction(); if(action==MotionEvent.ACTION_UP){//endonelineafterfingerrelease mCurrentLine.mEndX=x; mCurrentLine.mEndY=y; mCurrentLine=null; invalidate(); returntrue; } if(action==MotionEvent.ACTION_DOWN){ mCurrentLine=newLineElement(); addToPaths(mCurrentLine); mCurrentLine.mStartX=x; mCurrentLine.mStartY=y; returntrue; } if(action==MotionEvent.ACTION_MOVE){ mCurrentLine.mEndX=x; mCurrentLine.mEndY=y; mCurrentLine=newLineElement(); addToPaths(mCurrentLine); mCurrentLine.mStartX=x; mCurrentLine.mStartY=y; } if(mHandler.hasMessages(1)){ mHandler.removeMessages(1); } Messagemsg=newMessage(); msg.what=1; mHandler.sendMessageDelayed(msg,0); returntrue; } privatevoidaddToPaths(LineElementelement){ if(mLines==null){ mLines=newArrayList<LineElement>(); } mLines.add(element); } publicvoidcompactPaths(){ intsize=mLines.size(); intindex=size-1; if(size==0)return; intbaseAlpha=255-LineElement.ALPHA_STEP; intitselfAlpha; LineElementline; for(;index>=0;index--,baseAlpha-=LineElement.ALPHA_STEP){ line=mLines.get(index); itselfAlpha=line.mPaint.getAlpha(); if(itselfAlpha==255){ if(baseAlpha<=0){ ++index; break; } line.setAlpha(baseAlpha); }else{ itselfAlpha-=LineElement.ALPHA_STEP; if(itselfAlpha<=0){ ++index; break; } line.setAlpha(itselfAlpha); } } if(index>=size){ //allsub-pathshoulddisappear mLines=null; } elseif(index>=0){ //Log.i(TAG,"compactPathsfrom"+index+"to"+(size-1)); mLines=mLines.subList(index,size); }else{ //nosub-pathshoulddisappear } longinterval=40-SystemClock.elapsedRealtime()+mElapsed; if(interval<0)interval=0; Messagemsg=newMessage(); msg.what=1; mHandler.sendMessageDelayed(msg,interval); } }
这个示例还可以添加一些效果,比如让线条一边变淡一边变细。
以上所述是小编给大家介绍的Android使用自定义View绘制渐隐渐现动画的全部叙述,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!