效果截图

关键代码就是下面这个方法,可直接复制到你的项目,修改部分地方即可。

private void gouwuchedonghua() {

// 贝塞尔曲线起始点

int[] startPoint = new int[2];

// 贝塞尔曲线结束点

int[] endPoint = new int[2];

// 控制点

int[] relativeLayoutPoint = new int[2];

// 获取坐标点在页面布局中的位置

iv_jiahao.getLocationInWindow(startPoint);//起点 加号控件

gouwuche.getLocationInWindow(endPoint);//终点 购物车图片控件

rv_xq.getLocationInWindow(relativeLayoutPoint);//控制点 RecyclerView控件,如果加号位置是固定的一个,该控件可以换成整个布局的id

// 赋值贝塞尔曲线用到的点

PointF startF = new PointF();//起始点

PointF endF = new PointF();//结束点

PointF controllF = new PointF();//控制点

startF.x = startPoint[0];//起点横坐标

startF.y = startPoint[1] - relativeLayoutPoint[1];//起点纵坐标

endF.x = endPoint[0];//终点横坐标

endF.y = endPoint[1] - relativeLayoutPoint[1];//终点纵坐标

controllF.x = endF.x;

controllF.y = startF.y;

final ImageView imageView = new ImageView(this);

linearLayout_point.addView(imageView);

// imageView.setImageResource(R.mipmap.gouwuche);

Glide.with(this).load(Urls.BASE_URL + "/pro_photo/" + list.get(position).getImg()).error(R.mipmap.yuanxingtupian).into(imageView);

imageView.getLayoutParams().width = 64;//动画图片的宽

imageView.getLayoutParams().height = 64;//动画图片的高

imageView.setVisibility(View.VISIBLE);

imageView.setX(startF.x);

imageView.setY(startF.y);

// 估值器

ValueAnimator valueAnimator = ValueAnimator.ofObject(new BezierTypeEvaluator(controllF), startF, endF);

valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator animation) {

// 获取曲线坐标

PointF pointF = (PointF) animation.getAnimatedValue();

imageView.setX(pointF.x);

imageView.setY(pointF.y);

}

});

valueAnimator.addListener(new Animator.AnimatorListener() {

@Override

public void onAnimationStart(Animator animation) {

}

@Override

public void onAnimationEnd(Animator animation) {

linearLayout_point.removeView(imageView);

}

@Override

public void onAnimationCancel(Animator animation) {

}

@Override

public void onAnimationRepeat(Animator animation) {

}

});

// 购物车图标从缩小到放大的实现 属性动画,缩放

ObjectAnimator objectAnimatorX = ObjectAnimator.ofFloat(gouwuche, "scaleX", 0.6f, 1.0f);

ObjectAnimator objectAnimatorY = ObjectAnimator.ofFloat(gouwuche, "scaleY", 0.6f, 1.0f);

// 加速掉落

objectAnimatorX.setInterpolator(new AccelerateInterpolator());

objectAnimatorY.setInterpolator(new AccelerateInterpolator());

//设置动画播放顺序

AnimatorSet animatorSet = new AnimatorSet();

animatorSet.play(objectAnimatorX).with(objectAnimatorY).after(valueAnimator);

// 设置动画时间

animatorSet.setDuration(1000);

// 开始动画

animatorSet.start();

}

// 估值器

public class BezierTypeEvaluator implements TypeEvaluator{

private PointF controllF;

public BezierTypeEvaluator(PointF controllF) {

this.controllF = controllF;

}

@Override

public PointF evaluate(float fraction, PointF startValue, PointF endValue) {

PointF pointCur = new PointF();

// 基于三阶贝塞尔曲线公式,计算出曲线坐标点

// B(t)=(1-t)²P0+2(1-t)P1+t²P2,t€[0,1]

pointCur.x = (1 - fraction) * (1 - fraction) * startValue.x + 2 * fraction * (1 - fraction) * controllF.x + fraction * fraction * endValue.x;

pointCur.y = (1 - fraction) * (1 - fraction) * startValue.y + 2 * fraction * (1 - fraction) * controllF.y + fraction * fraction * endValue.y;

return pointCur;

}

}

页面布局代码:

注意:布局最外层一定要用RelativeLayout(相对布局),我一开始用的LinearLayout(线性布局),每次动画执行购物车那一栏总是往起蹦跶,也可以尝试其它布局。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐