java实现小球自由下落回弹_自定义view实现自由下落回弹动画

public class ReceiveSalaryAnim extendsView {private static final String TAG = ReceiveSalaryAnim.class.getSimpleName();int[] location = new int[2];private Path mPath = newPath();privatePathMeasure mPm;private int mPointPos = 0; //小球运动的位置

private static final int STATE_STATIC = 0; //处于静止状态

private static final int STATE_MOVING = 1;private int mDirection =STATE_STATIC;privateDisplayMetrics dm;privateDrawable mBall;privateRect mBallRect;private static final int INIT_HEIGHT = 60;private intmLineEndPosY;private Paint mPaint = newPaint();publicReceiveSalaryAnim(Context context, AttributeSet attrs) {super(context, attrs);

dm=context.getResources().getDisplayMetrics();

mBall=context.getResources().getDrawable(R.drawable.btn_icon_download);

mBallRect= newRect();

}private voidreceiveSalary() {if (mDirection !=STATE_STATIC) {return;

}

mDirection=STATE_MOVING;

setClickable(false);

invalidate();

}

@Overrideprotected void onLayout(boolean changed, int left, int top, int right, intbottom) {super.onLayout(changed, left, top, right, bottom);float offset = INIT_HEIGHT * dm.density - mBall.getIntrinsicHeight() / 2;

getLocationOnScreen(location);

mPath.moveTo(location[0], location[1] +offset);

mPath.cubicTo(location[0], location[1] + offset + (offset / 4), location[0], location[1] +offset+ (offset * 4), location[0], location[1] +offset);

mPm= new PathMeasure(mPath, false);

mPm.getPosTan(mPm.getLength()- 1, pos, tan);

mLineEndPosY= (int) (pos[1]);

}

@Overridepublic booleanonTouchEvent(MotionEvent arg0) {if (mDirection !=STATE_STATIC) {return super.onTouchEvent(arg0);

}if (arg0.getAction() ==MotionEvent.ACTION_UP) {//getLocationInWindow(location);

setBallRect();final int x = (int) arg0.getX();final int y = (int) arg0.getY();if(mBallRect.contains(x, y)) {

receiveSalary();return super.onTouchEvent(arg0);

}

}return super.onTouchEvent(arg0);

}private voidsetBallRect() {

mBallRect.set(location[0], mLineEndPosY - mBall.getIntrinsicHeight() / 2,

location[0] + mBall.getIntrinsicWidth(), mLineEndPosY + mBall.getIntrinsicHeight() / 2);

}float[] pos = new float[2];float[] tan = new float[2];//将均匀点映射到正弦曲线,获得由0加速,然后回弹减速到0的效果

private float getAccelerationPoint(float len, floatpoint) {return (float) (len * (Math.sin((2 * point - len) * Math.PI / (2 * len)) / 2 + 0.5));

}

@Overrideprotected voidonDraw(Canvas canvas) {super.onDraw(canvas);float lineStartX = location[0];float lineStartY = location[1];float lineEndX =lineStartX;float lineEndY =mLineEndPosY;//取 drawable 的长宽

int w =mBall.getIntrinsicWidth();int h =mBall.getIntrinsicHeight();if (mDirection != STATE_STATIC && mPointPos

mPm.getPosTan(getAccelerationPoint(mPm.getLength(), mPointPos), pos, tan);

lineEndY= pos[1];

}else{if (mPointPos > 0) {

mPm.getPosTan(mPm.getLength()- 1, pos, tan);

lineEndY= pos[1];

}

setClickable(true);

mDirection=STATE_STATIC;

mPointPos= 0;

setBallRect();

}//draw line from location[1] to lineEndY, draw ball from//lineEndY-ball's height

canvas.save();

mPaint.setColor(0xffff0000);

mPaint.setStyle(Paint.Style.STROKE);

mPaint.setStrokeWidth(15);

canvas.drawLine(lineStartX+ w / 2, lineStartY, lineEndX + w / 2, lineEndY, mPaint);

canvas.restore();

canvas.save();//取 drawable 的颜色格式

Bitmap.Config config = mBall.getOpacity() != PixelFormat.OPAQUE ?Bitmap.Config.ARGB_8888

: Bitmap.Config.RGB_565;//建立对应 bitmap//Bitmap bitmap = Bitmap.createBitmap(w, h, config);

mBall.setBounds((int) lineEndX, (int) lineEndY - h / 2, (int) lineEndX + w, (int) lineEndY + h / 2);//把 drawable 内容画到画布中

mBall.draw(canvas);

canvas.restore();if (mDirection != STATE_STATIC && mPointPos

mPointPos+= 8;

invalidate();

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值