1. 程式人生 > >一個容易理解Path動畫的例子。

一個容易理解Path動畫的例子。

A:   導讀


讓我們先看一張動圖,這是一個查詢類的App的歡迎頁。

正準備做的歡迎頁,發現還不錯,決定把這個例子分享出來,幾行程式碼就能瞭解Path繪製的動畫路徑。

關於Path網上的教程已經很多了,這裡僅僅是針對這個例子結合PathPathMeasure來講解原理。


 

B:這裡一共分為幾步


1、因為是歡迎頁,所以展示時間不宜過久。此處設定為了3S左右。


2、前期素材圖示:書本、搜尋、條形擬文字


3、規定好在螢幕中央,搜尋圖示在書本上轉2圈後,漸顯出文字,以此來表達互動結果。


一、畫出佈局


讓書本居中,條形文字相對於書本左上角,並設定alpha=0來做好準備。如果專案是基於2.3,請使用NineOldroid庫在程式碼中來設定透明度。

規定好搜尋的範圍,這裡的範圍是個自定義View,暫且稱為PathSearch,稍大於書本即可。



二、宣告畫筆和路徑、和搜尋圖示素材


規定好動畫路徑,讓搜尋圖示繞中心轉圈就可以接下來我們來通過程式碼實現,我們在程式碼中先畫出路徑。


	Paint mPaint;
	Path mPath;
	Bitmap mBitmap;

	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.//

將指定的弧新增到路徑作為新輪廓。

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


-RectF 圓的左上角位置和右下角位置,構造方法(floatleft,floattop, float right, float bottom)

-startAngle 從哪個角度開始畫

-sweepAngle 要畫多少度


來張圖片感受一下什麼意思

規定好了RectF,那麼就能得出這個圓的範圍.這個紅圓僅作為標識範圍作用。



假設我們startAngle設定為0sweepAngle設定為90,那麼將會成為這個樣子。當sweepAngle設定為360度時,我們將得出整個圓。


為了計算出RectF的位置,我們可以在腦中構一下圖,具象化後如下,可以看到leftright在框的1/4位置,bottomright在框的3/4位置



那麼這個時候可以通過重寫onSizeChanged來得出RectF

    int distance=w/4; //距離=寬除以4;
    RectF rectF=new RectF(distance,distance,distance*3,distance*3);

、通過API畫好規定範圍


此時我們可以將搜尋圖示放置上去,由於該例子的搜尋圖示起始位置在右下角

所以我們設定startAngle45sweepAngle360讓圖示繞圓旋轉一週,呼叫mPath.addArc(rectF,45,360);方法。

路徑有了,接下來如何讓搜尋圖示沿著路徑動起來呢,我們可以藉助PathMeasure和屬性動畫來完成。

PathMeasure,可以理解成他讓你的Path變成了一條直線,並且提供了長度以及每一個點的座標,來張圖感受一下。


宣告、測量


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


五、接下來就可以來完成動畫了


通過mPathMeasure拿到Path的長度mPathMeasure.getLength()。我們來結合屬性動畫來完成這一過程。

宣告一個陣列來存放每個點的座標。


   	float[] pos=new float[2];


	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


擴充套件:

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