最近项目需要用到京东的签到功能,所以就模仿京东的签到写了一个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下载