最近項目需要用到京東的簽到功能,所以就模仿京東的簽到寫了一個demo。(文章底部有demo)
先看效果
demo上主要使用了有2個知識點,一個是屬性動畫,一個是canvas。
屬性動畫:使用了旋轉,透明,平移,縮放。canvas,使用了繪製圖片到畫布上。並且不斷繪製改變他們的位置直到屏幕的位置中心。
寫demo遇到的的幾個問題。
(1) ,抽籤翻卡片主要要解決幾個問題。1,手指點擊6張中的任意一張需要平移到屏幕的中心,並且還要能回到原來的位置。2,旋轉效果的實現。3,禮花的平移位置。
(2), 抽籤翻卡片要注意的幾個問題。1,圖片旋轉之前的是默認的圖片,但是旋轉之後圖片上的文字和圖片是反過來的。2 注意第一和最後一張張圖片的起始位置。3,bitmap的釋放。
(3)未解決問題:1,好像屬性動畫第二次作用控件對象使用平移就不好用了位置亂跑。(2),我把控件在邏輯代碼裏放大1.5倍之後再使用組合屬性動畫也不用使用了,平移加縮放,出現的問題是縮放不能使用。
縮放不能使用了,去掉縮放,平移就可以使用了。
先看第一個如何解決: 1,手指點擊6張中的任意一張需要平移到屏幕的中心,並且還要能回到原來的位置。
當手指點擊某一張圖片的時候就記錄下,卡片的(x,y)座標,然後在彈出的新蒙層指定位置上顯示一張和底部卡片一模一樣的卡片。當卡片顯示出來的時候使用旋轉,放大,平移動畫使其移動到屏幕中間的位置,所以這就是個假象。實際上還是一張圖片在一個蒙層上旋轉。只不過需要把假象做到底,還要把下面手指點擊的卡片給隱藏。看起來是一張在旋轉。
下面是關鍵部分代碼;
先看第二個如何解決:2,旋轉效果的實現。
屬性動畫能做到補間動畫不能實現的效果。能夠改變其控件的位置,補間動畫是個假象,形動神不動。其實旋轉效果很好寫。只需要幾句代碼,但是需要注意點是,平移的位置是屏幕的中心。
下面是關鍵代碼:
mTranslationX = ObjectAnimator.ofFloat(tv_NoShOW_LL, "translationX", 0.0f, mCuurentX);
mAnimator2 = ObjectAnimator.ofFloat(tv_NoShOW_LL, "translationY", 0.0f, mCuurentY);
mAnimator3 = ObjectAnimator.ofFloat(tv_NoShOW_LL, "rotationY", 0f, 180f);
mAnimator4 = ObjectAnimator.ofFloat(tv_NoShOW_LL, "scaleX", 1f, 1.5f);
mAnimator5 = ObjectAnimator.ofFloat(tv_NoShOW_LL, "scaleY", 1f, 1.5f);
mAnimatorSet = new AnimatorSet();
mAnimatorSet.play(mBackgroundColor).with(mTranslationX).with(mAnimator2).with(mAnimator3).with(mAnimator4).with(mAnimator5);
其中,mCurrentx,mCurrentY 是屏幕的中心點的位置。
int mWidth = mWm.getDefaultDisplay().getWidth(); //屏幕的寬
int mHeight = mWm.getDefaultDisplay().getHeight(); //屏幕的高
float mCuurentX = mWidth / 2 - x - mImg_width; //mImg_width是圖片的高
float mCuurentY = mHeight / 2 - y - mImg_height;
3,禮花的平移位置。
(1) 繪製4個圖片
bitmap1 = BitmapFactory.decodeResource(getResources(), R.mipmap.lihua_a1);
bitmap2 = BitmapFactory.decodeResource(getResources(), R.mipmap.lihua_a2);
bitmap3 = BitmapFactory.decodeResource(getResources(), R.mipmap.lihua_a3);
bitmap4 = BitmapFactory.decodeResource(getResources(), R.mipmap.lihua_a4);
(2)平移到屏幕的中間位置
matrix.postTranslate(valeusOjbject.x, valeusOjbject.y); //postTranslate裏面的dx,dy是滾動的偏移量。
canvas.drawBitmap(hashMap.get(1), matrix, paint); //hashMap.get(1) 獲取一個bitmap
(4),1,圖片旋轉之前的是默認的圖片,但是旋轉之後圖片上的文字和圖片是反過來的。
圖片旋轉之後圖片,和文字是反過來的所以要在動畫執行的2分之1的時間的時候把圖片給旋轉180扭轉過來。
if (playTime > 500 && is) {
is = false;
mRotationYs = ObjectAnimator.ofFloat(tv_NoShOW_Img, "rotationY", 0f, 180f);
mRotationYs1 = ObjectAnimator.ofFloat(tv_NoShOw_Centent, "rotationY", 0f, 180f);
mRotationYs2 = ObjectAnimator.ofFloat(tv_NoShOw_Name_Title, "rotationY", 0f, 180f);
playTime 是獲取的動畫執行的時間。
(5) 注意第一和最後一張張圖片的起始位置。
注意我把禮花的圖片放到了中間的位置,1080/5==space , space 就是間距。但是我們不能以次排列, 如果以次排列第一張圖的位置就是0,第二張的圖片是216所以 我們必須把圖片放到,第一個間距的中間。 所以的x=1080/5-mImage/2。必須減去圖片的2分支一讓圖片在216的108位置居中纔可以。否則就會出現第一張和最後張。 間距一個大一個小。
3,bitmap的釋放。
我在繪製了4張圖片後,必須要等動畫執行之後recycly().釋放內存。但是在監聽的onAnimationEnd()方法裏嗎不能執行釋放的操作,應爲,onAnimationEnd方 法執行的時候,動畫並沒有完全結束 .
所以可以在view的銷燬的時候 onDeacheForWindow() 裏釋放了內存。這樣就可以解決釋放內存的問題。
demo下載