Android自定义View实现搜索动画效果
2017-12-04 19:15
761 查看
Android自定义View实现搜索动画效果
近来看到的一个效果,不多bb上图画图分析
wtf?上图就是我们需要实现这个效果应该画的图? 对的没错,只是你还需要一点动画的帮忙。
由效果我们可以分析这个搜索的状态可以分为原始状态NONE,开始搜索状态START,正在搜索状态SEARCHING,搜索完成状态END
可以将以上4种状态图解一下分别是如图所示:
源代码
代码如下所示,注释有很好的说明,如果相关方法不知道具体使用,请面向百度,或者找我要资料/** * Created by zhanghs on 2017/12/4/004. */ public class SearchIcon extends View { private int mWidth,mHeight;//画布的宽高 private float smallRadii=25f,bigRadii=50f,varySet=0,start,end,length;//大圆的半径,及小圆的半径,变化的参数,和三个变量,下面有说明 private Path pathSearch,pathBig,pathStart,pathSearching,pathEnd;//绘制的路径 private Paint paintNormal;//画笔 private float[] pointXY=new float[2];//获取搜索的把柄的末尾坐标 private PathMeasure measureSearch=new PathMeasure(),measureBig=new PathMeasure();//测量path的工具 private TYPE type=TYPE.NONE;//状态 private ValueAnimator animatorStart,animatorSearching,animatorDone; enum TYPE{ NONE,START,SEARCHING,DONE } private Handler handler=new Handler(){ @Override public void handleMessage(Message msg) { if(msg.what==0){ switch (type){ case NONE://默认状态 type=TYPE.START; animatorStart.start(); break; case START://开始搜索 type=TYPE.SEARCHING; animatorSearching.start(); break; case SEARCHING://正在搜索 type=TYPE.DONE; animatorDone.start(); break; case DONE://搜索完成 type=TYPE.NONE; break; default: break; } } } }; public SearchIcon(Context context, @Nullable AttributeSet attrs) { super(context, attrs); initPaint(); initPath(); initValueAnimator(); } /** * 初始化动画 */ private void initValueAnimator() { animatorStart=ValueAnimator.ofFloat(0f,1.000f); animatorStart.addUpdateListener(upListener); animatorStart.setInterpolator(new LinearInterpolator()); animatorStart.addListener(listener); animatorStart.setRepeatCount(0); animatorStart.setDuration(1500); animatorSearching=ValueAnimator.ofFloat(0f,1.000f); animatorSearching.addUpdateListener(upListener); animatorSearching.setInterpolator(new LinearInterpolator()); animatorSearching.addListener(listener); animatorSearching.setRepeatCount(2); animatorSearching.setDuration(2000); animatorDone=ValueAnimator.ofFloat(1.000f,0f); animatorDone.addUpdateListener(upListener); animatorDone.setInterpolator(new LinearInterpolator()); animatorDone.addListener(listener); animatorDone.setRepeatCount(0); animatorDone.setDuration(1500); } /** * 初始化路径 */ private void initPath() { pathSearch=new Path(); pathSearch.addArc(new RectF(-smallRadii,-smallRadii,smallRadii,smallRadii),45,359.9f); pathBig=new Path(); pathBig.addArc(new RectF(-bigRadii,-bigRadii,bigRadii,bigRadii),45,359.9f); measureBig=new PathMeasure(); measureBig.setPath(pathBig,false); measureBig.getPosTan(0,pointXY,null); pathSearch.lineTo(pointXY[0],pointXY[1]); measureSearch=new PathMeasure(); measureSearch.setPath(pathSearch,false); length= (float) (Math.PI*bigRadii*2/4); } /** * 初始化画笔 */ private void initPaint() { paintNormal=new Paint(); paintNormal.setAntiAlias(true); paintNormal.setStrokeWidth(5); paintNormal.setColor(Color.BLUE); paintNormal.setStyle(Paint.Style.STROKE); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.translate(mWidth/2,mHeight/2); drawSearch(canvas); } /** * 画 * @param canvas */ private void drawSearch(Canvas canvas) { switch (type){ case NONE: canvas.drawPath(pathSearch,paintNormal); break; case START: pathStart=new Path(); //这里是画原pathSearch中截取的一段路径 measureSearch.getSegment(varySet*measureSearch.getLength(),measureSearch.getLength(),pathStart,true); canvas.drawPath(pathStart,paintNormal); break; case SEARCHING: end=measureBig.getLength()*varySet; start=(float) (end - ((0.5 - Math.abs(varySet - 0.5)) * length)); pathSearching=new Path(); //这里是画原pathBig中截取的一段路径 measureBig.getSegment(start,end,pathSearching,true); canvas.drawPath(pathSearching,paintNormal); break; case DONE: pathEnd=new Path(); //这里是画原pathSearch中截取的一段路径 measureSearch.getSegment(varySet*measureSearch.getLength(),measureSearch.getLength(),pathEnd,true); canvas.drawPath(pathEnd,paintNormal); break; default: break; } } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mWidth=w; mHeight=h; } private ValueAnimator.AnimatorUpdateListener upListener= new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { varySet= (float) valueAnimator.getAnimatedValue(); invalidate(); } }; private Animator.AnimatorListener listener=new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animator) { } @Override public void onAnimationEnd(Animator animator) { handler.sendEmptyMessage(0); } @Override public void onAnimationCancel(Animator animator) { } @Override public void onAnimationRepeat(Animator animator) { } }; /** * 开始搜索 */ public void start(){ if(type==TYPE.NONE){ handler.sendEmptyMessage(0); } } }
效果图
注意这个控件的搜索完成是要你自己去控制的,我这里只是为了展示写的很简单,看你操作就行了 抠脚来的,不喜勿喷
相关文章推荐
- Android自定义View实现loading动画加载效果
- Android自定义View之实现流行的新浪微博底部菜单:高仿“咸鱼APP”的底部菜单动画效果。
- Android自定义viewGroup实现点击动画效果
- Android 自定义view实现水波纹动画效果
- android自定义TextView实现安卓手机开机android文字Log的动画效果
- Android属性动画与自定义View——实现vivo x6更新系统的动画效果
- Android自定义View: 如何实现类钟摆的动画效果?
- Android自定义View 实现水波纹动画引导效果
- Android自定义view实现阻尼效果的加载动画
- Android 自定义view和属性动画实现充电进度条效果
- Android进阶——自定义View之继承系统控件实现自带删除按钮动画效果和软键盘自动悬浮于文本框下方
- Android实现带动画效果的自定义View
- Android应用程序入门 推箱子游戏开发(一) surfaceView 实现动画效果
- Android自定义View实现HTML图文环绕效果
- Android中用ViewPager实现多页面滑动切换及动画效果的实例
- Android利用ViewFlipper实现屏幕切换动画效果(上)
- Android利用ViewFlipper实现屏幕切换动画效果(下)
- android 自定义ViewGroup和对view进行切图动画实现滑动菜单SlidingMenu
- android 自定义ImageView实现图片手势滑动,多点触摸放大缩小效果
- Android利用ViewFlipper实现屏幕切换动画效果