Android 自定义View以及ValueAnimator学习

     看了ApiDemo里面的BoucingBall,觉得挺好的,所以特地学习了一下,将代码注释后贴到这里,以便以后学习。

class BallView extends View implements ValueAnimator.AnimatorUpdateListener{
		private static final int RED = 0xffFF8080;
		private static final int BLUE = 0xff8080FF;
		private static final int CYAN = 0xff80ffff;
		private static final int GREEN = 0xff80ff80;

		private ArrayList<ShapeHolder> balls = new ArrayList<ShapeHolder>();

	
		public BallView(Context context, AttributeSet attrs, int defStyle) {
			super(context, attrs, defStyle);
			// TODO Auto-generated constructor stub
		}

		public BallView(Context context) {
			this(context, null);
		}

		public BallView(Context context, AttributeSet attrs) {
			super(context, attrs);
			
			//自定义View的背景切换动画
			ValueAnimator colorAnim = ObjectAnimator.ofInt(this,
					"backgroundColor", RED, BLUE,CYAN,GREEN);
			colorAnim.setDuration(3000L);
			colorAnim.setEvaluator(new ArgbEvaluator());
			colorAnim.setRepeatCount(ValueAnimator.INFINITE);
			colorAnim.setRepeatMode(ValueAnimator.REVERSE);
			colorAnim.start();
		}

		@Override
		protected void onDraw(Canvas canvas) {
			//在画布上绘制图形
			for(ShapeHolder holder:balls){
				canvas.save();
				canvas.translate(holder.getX(), holder.getY());
				holder.getmShapeDrawable().draw(canvas);
				canvas.restore();
			}
		}

		@Override
		public boolean onTouchEvent(MotionEvent event) {
			if (event.getAction() != MotionEvent.ACTION_DOWN
					&& event.getAction() != MotionEvent.ACTION_MOVE) {
				return false;
			}
			
			
			ShapeHolder newBall = addBall(event.getX(), event.getY());

			float startY = newBall.getY();
			float endY = getHeight() - 50f;

			float h = getHeight();
			float eventy = event.getY();

			int duration = (int) (500 * ((h - eventy) / h));
			
			//设置加速掉落的效果
			ValueAnimator bounceAnim = ObjectAnimator.ofFloat(newBall, "y",
					startY, endY);
			bounceAnim.setDuration(duration);
			bounceAnim.setInterpolator(new AccelerateInterpolator());
			
			//当掉落到底部的时候,球体压扁,高度降低
			ValueAnimator squashAnim1 = ObjectAnimator.ofFloat(newBall, "x",
					newBall.getX(), newBall.getX() - 25);
			squashAnim1.setDuration(duration /4);
			squashAnim1.setRepeatCount(1);
			squashAnim1.setRepeatMode(ValueAnimator.REVERSE);
			squashAnim1.setInterpolator(new DecelerateInterpolator());

			ValueAnimator squashAnim2 = ObjectAnimator.ofFloat(newBall,"width", 
					newBall.getWidth(), newBall.getWidth() + 50);
			squashAnim2.setDuration(duration /4);
			squashAnim2.setRepeatCount(1);
			squashAnim2.setRepeatMode(ValueAnimator.REVERSE);
			squashAnim2.setInterpolator(new DecelerateInterpolator());

			ValueAnimator strechAnim1 = ObjectAnimator.ofFloat(newBall, "y",
					endY, endY + 25);
			strechAnim1.setDuration(duration /4);
			strechAnim1.setRepeatCount(1);
			strechAnim1.setRepeatMode(ValueAnimator.REVERSE);
			strechAnim1.setInterpolator(new DecelerateInterpolator());

			ValueAnimator strechAnim2 = ObjectAnimator.ofFloat(newBall,"height",
					newBall.getHeight(), newBall.getHeight() - 25);
			strechAnim2.setDuration(duration /4);
			strechAnim2.setRepeatCount(1);
			strechAnim2.setRepeatMode(ValueAnimator.REVERSE);
			strechAnim2.setInterpolator(new DecelerateInterpolator());

			ValueAnimator bounceBack = ObjectAnimator.ofFloat(newBall, "y",
					endY, startY+25);
			bounceBack.setDuration(duration);
			bounceAnim.setInterpolator(new DecelerateInterpolator());

			AnimatorSet set = new AnimatorSet();
			set.play(bounceAnim).before(squashAnim1);
			
			set.play(squashAnim1).with(squashAnim2);
			set.play(squashAnim1).with(strechAnim1);
			set.play(squashAnim1).with(strechAnim2);
			set.play(bounceBack).after(strechAnim2);
			
			//逐渐消失
			ValueAnimator fadeAnimator = ObjectAnimator.ofFloat(newBall,
					"alpha", 1F, 0F);
			fadeAnimator.setDuration(600L);

			fadeAnimator.addListener(new AnimatorListenerAdapter() {

				@Override
				public void onAnimationEnd(Animator animation) {
					// TODO Auto-generated method stub
					balls.remove(((ObjectAnimator) animation).getTarget());
				}

			});

			AnimatorSet animationSet = new AnimatorSet();
			animationSet.play(set).before(fadeAnimator);
			
			animationSet.start();
			return true;
		}

		/**
		 * 生成一个球
		 * @param x
		 * @param y
		 * @return
		 */
		public ShapeHolder addBall(float x, float y) {
			// 构造一个圆形的图案
			OvalShape oval = new OvalShape();
			oval.resize(50f, 50f);

			ShapeDrawable draw = new ShapeDrawable(oval);
			ShapeHolder holder = new ShapeHolder(draw);
			holder.setX(x - 25);
			holder.setY(y - 25);

			int red = (int) (Math.random() * 255);
			int green = (int) (Math.random() * 255);
			int blue = (int) (Math.random() * 255);

			int color = 0xff000000 | red << 16 | green << 8 | blue;

			int darkColor = 0xff000000 | red / 4 << 16 | green / 4 << 8 | blue
					/ 4;
			Paint paint = draw.getPaint();
			RadialGradient gradient = new RadialGradient(12.5f, 12.5f, 50f,
					color, darkColor, Shader.TileMode.CLAMP);
			paint.setShader(gradient);

			holder.setmRadialGradient(gradient);
			holder.setmPaint(paint);

			balls.add(holder);

			return holder;
		}

		@Override
		public void onAnimationUpdate(ValueAnimator animation) {
			// TODO Auto-generated method stub
			invalidate();
		}
}

转载于:https://my.oschina.net/fengcunhan/blog/52763

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值