一个容易理解 Path 动画的例子。

1,402 阅读5分钟
原文链接: blog.csdn.net

A:   导读


让我们先看一张动图,这是一个查询类的App的欢迎页。

正准备做的欢迎页,发现还不错,决定把这个例子分享出来,几行代码就能了解 Path绘制的动画路径。

关于Path网上的教程已经很多了,这里仅仅是针对这个例子结合PathPathMeasure来讲解原理。


 

B:这里一共分为几步


1、因为是欢迎页,所以展示时间不宜过久。此处设置为了3S左右。


2、前期素材图标:书本、搜索、条形拟文字


3、规定好在屏幕中央,搜索图标在书本上转2圈后,渐显出文本 ,以此来表达交互结果。


一、画出布局


让书本居中,条形文字相对于书本左上角,并设置alpha=0来做好准备。如果项目是基于2.3,请使用NineOldroid库在代码中来设置透明度。

规定好搜索的范围,这里的范围是个自定义 View,暂且称为PathSearch ,稍大于书本即可。



二、声明画笔和路径、和搜索图标素材


规定好动画路径,让搜索图标绕中心转圈就可以接下来我们来通过代码实现 ,我们在代码中先画出路径。


  1. <span style="white-space:pre">  </span>Paint mPaint;  
  2. <span style="white-space:pre">  </span>Path mPath;  
  3. <span style="white-space:pre">  </span>Bitmap mBitmap;  
	Paint mPaint;
	Path mPath;
	Bitmap mBitmap;

  1. mPaint=new Paint(Paint.ANTI_ALIAS_FLAG);  
  2. mPaint.setStyle(Paint.Style.STROKE);  
  3. mPaint.setColor(Color.GREEN);  
  4.   
  5. mPath=new Path();  
  6. mBitmap= BitmapFactory.decodeResource(context.getResources(), R.drawable.wel_search);  
	mPaint=new Paint(Paint.ANTI_ALIAS_FLAG);
	mPaint.setStyle(Paint.Style.STROKE);
	mPaint.setColor(Color.GREEN);

	mPath=new Path();
	mBitmap= BitmapFactory.decodeResource(context.getResources(), R.drawable.wel_search);

三、接下来在中心画出一个圆,这里需要用到Path的一个API 


Add the specified arc to the path as a new contour.//将指定的弧添加到路径作为新轮廓。

  1. public void addArc(RectF oval, float startAngle, float sweepAngle)  
    public void addArc(RectF oval, float startAngle, float sweepAngle)


-RectF 圆的左上角位置和右下角位置,构造方法(floatleft, float top, float right, float bottom)

-startAngle 从哪个角度开始画

-sweepAngle 要画多少度


来张图片感受一下什么意思

规定好了RectF,那么就能得出这个圆的范围.这个红圆仅作为标识范围作用。


假设我们startAngle设置为0sweepAngle设置为 90,那么将会成为这个样子。当sweepAngle设置为360度时,我们将得出整个圆。


为了计算出RectF的位置,我们可以在脑中构一下图,具象化后如下,可以看到leftright在框的1/4位置,bottomright在框的 3/4位置



那么这个时候可以通过重写onSizeChanged来得出RectF

  1. int distance=w/4//距离=宽除以4;  
  2. RectF rectF=new RectF(distance,distance,distance*3,distance*3);  
    int distance=w/4; //距离=宽除以4;
    RectF rectF=new RectF(distance,distance,distance*3,distance*3);

、通过API画好规定范围


此时我们可以将搜索图标放置上去,由于该例子的搜索图标起始位置在右下角

所以我们设置startAngle45 sweepAngle360让图标绕圆旋转一周,调用 mPath.addArc(rectF,45,360);方法。

路径有了,接下来如何让搜索图标沿着路径动起来呢,我们可以借助PathMeasure和属性动画来完成。

PathMeasure,可以理解成他让你的Path变成了一条直线,并且提供了长度以及每一个点的坐标,来张图感受一下。


声明、测量


  1. PathMeasure mPathMeasure;     
    PathMeasure mPathMeasure;	
  1. mPathMeasure=new PathMeasure(mPath,true);  
    mPathMeasure=new PathMeasure(mPath,true);


五、接下来就可以来完成动画了


通过mPathMeasure拿到Path的长度mPathMeasure.getLength() 。我们来结合属性动画来完成这一过程。

声明一个数组来存放每个点的坐标。


  1. <span style="white-space:pre">  </span>float[] pos=new  float[2];  
   	float[] pos=new float[2];


  1. <span style="white-space:pre">  </span>ValueAnimator valueAnimatorCompat= ValueAnimator.ofFloat(0,mPathMeasure.getLength());  
  2.     valueAnimatorCompat.setDuration(1200);//一圈1.2S  
  3.     valueAnimatorCompat.setStartDelay(500);//延时0.5S开始动画   
  4.     valueAnimatorCompat.setInterpolator(new DecelerateInterpolator());//减速差值器  
  5.     valueAnimatorCompat.setRepeatCount(1);//设置重复1次  
  6.   
  7.     //如何拿到不同时段的坐标呢,我们需要监听动画的Update  
  8.   
  9.     valueAnimatorCompat.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {  
  10.         @Override  
  11.         public void onAnimationUpdate(ValueAnimator animation) {  
  12.                 float value= (float) animation.getAnimatedValue(); //获得0到mPathMeasure.getLength()之间的位置  
  13.               
  14.                 mPathMeasure.getPosTan(value,pos,null);//获得该位置上的x、y坐标存储在pos里  
  15.               
  16.                 postInvalidate();//通知UI绘制  
  17.          }  
  18.     });  
	ValueAnimator valueAnimatorCompat= ValueAnimator.ofFloat(0,mPathMeasure.getLength());
	valueAnimatorCompat.setDuration(1200);//一圈1.2S
	valueAnimatorCompat.setStartDelay(500);//延时0.5S开始动画	
	valueAnimatorCompat.setInterpolator(new DecelerateInterpolator());//减速差值器
	valueAnimatorCompat.setRepeatCount(1);//设置重复1次

	//如何拿到不同时段的坐标呢,我们需要监听动画的Update

	valueAnimatorCompat.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    	@Override
    	public void onAnimationUpdate(ValueAnimator animation) {
        		float value= (float) animation.getAnimatedValue();//获得0到mPathMeasure.getLength()之间的位置
			
        		mPathMeasure.getPosTan(value,pos,null);//获得该位置上的x、y坐标存储在pos里
			
        		postInvalidate();//通知UI绘制
   		 }
	});

六、onDraw绘制图片位置

为了让搜索图片显示到路径右下方, 所以计算出的坐标减去了图片宽高的一半

canvas.drawBitmap(mBitmap,pos[0]-mBitmap.getWidth()/2,pos[1]-mBitmap.getHeight()/2,mPaint);


七、最后,通过监听属性动画完成来显示文字条内容即可。

源码:


https://github.com/vvinner/PathSearchs


★★★★★★★★有用的话Star一下吐舌头★★★★★★★★★


扩展:

在任何View上添加view:http://blog.csdn.net/dqmj2/article/details/51721193