写点什么

使用二阶贝塞尔曲线实现添加购物车动画,移动互联网开发专业

用户头像
Android架构
关注
发布于: 13 小时前


  1. 如图所示主要有三个点,起点、终点、以及贝塞尔曲线的控制点

  2. 起点即点击的 View 的位置,一般来说用如下方式即可取得。startPosition[0]为 x 轴开始坐标,startPosition[1]为 Y 轴终点坐标,两点可以看作对角线上面的两个端点(左上角 x 坐标,右下角 y 坐标)


//贝塞尔起始数据点 int[] startPosition = new int[2];view.getLocationOnScreen(startPosition);


  1. 终点即购物车篮子的位置,与起点类似


mShoppingCart.getLocationInWindow(endPosition);


  1. 控制点,我选的控制点为上图的 C 点,即 A 点的 y 坐标,B 点的 X 坐标


controlPosition[0] = endPosition[0];controlPosition[1] = startPosition[1];


  1. 需要注意的地方,我不清楚是不是因为我的布局的问题,获取到的点击的 A 点总是会有一个偏移,后来经同事提醒,减去了 TabLayout 的坐标的 y 轴坐标即位置才可以。


// 起点 int[] startPosition;// 终点 int[] endPosition = new int[2];// 贝塞尔控制点 int[] controlPosition = new int[2];// tablayout 位置 int[] tablayoutPosition = new int[2];


startPosition = data.getStartPosition();mShoppingCart.getLocationInWindow(endPosition);mTabLayout.getLocationInWindow(tablayoutPosition);// 处理起点 y 坐标偏移的问题 startPosition[1] = startPosition[1] - tablayoutPosition[1] - mTabLayout.getHeight();// 终点进行一下居中处理 endPosition[0] = endPosition[0] + (mShoppingCart.getWidth() / 2);controlPosition[0] = endPosition[0];controlPosition[1] = startPosition[1];


  1. 通过PathquadTo方法绘制贝塞尔曲线,使用PathMeasure获取点的坐标(借助ValueAnimator.ofFloat()配合getPosTan()来获取坐标)


Path path = new Path();path.moveTo(startPosition[0], startPosition[1]);path.quadTo(controlPosition[0], controlPosition[1], endPosition[0], endPosition[1]);PathMeasure pathMeasure = new PathMeasure();// false 表示 path 路径不闭合 pathMeasure.setPath(path, false);


// ofFloat


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


是一个生成器 ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, pathMeasure.getLength());// 匀速线性插值器 valueAnimator.setInterpolator(new LinearInterpolator());valueAnimator.setDuration(800);valueAnimator.addUpdateListener(animation -> {float value = (Float) animation.getAnimatedValue();pathMeasure.getPosTan(value, currentPosition, null);imageView.setX(currentPosition[0]);imageView.setY(currentPosition[1]);});valueAnimator.start();


  1. 下面是用属性动画给购物车篮子做了一个放大缩小的动画效果


// mShoppingCart 是 ViewObjectAnimator shoppingCartX = ObjectAnimator.ofFloat(mShoppingCart, "scaleX", 1.0f, 1.3f, 1.0f);ObjectAnimator shoppingCartY = ObjectAnimator.ofFloat(mShoppingCart, "scaleY", 1.0f, 1.3f, 1.0f);shoppingCartX.setInterpolator(new AccelerateInterpolator());shoppingCartY.setInterpolator(new AccelerateInterpolator());AnimatorSet shoppingCart = new AnimatorSet();shoppingCart.play(shoppingCartX).with(shoppingCartY);shoppingCart.setDuration(800);shoppingCart.start();

三、稍完整的大部分代码

private void AddAnimation(AddEventBean data) {// 起点 int[] startPosition;// 终点 int[] endPosition = new int[2];// 贝塞尔控制点 int[] controlPosition = new int[2];// 当前位置 float[] currentPosition = new float[2];// tablayout 位置 int[] tablayoutPosition = new int[2];


startPosition = data.getStartPosition();mShoppingCart.getLocationInWindow(endPosition);mTabLayout.getLocationInWindow(tablayoutPosition);// 处理起点 y 坐标偏移的问题 startPosition[1] = startPosition[1] - tablayoutPosition[1] - mTabLayout.getHeight();// 终点进行一下居中处理 endPosition[0] = endPosition[0] + (mShoppingCart.getWidth() / 2);controlPosition[0] = endPosition[0];controlPosition[1] = startPosition[1];


final ImageView imageView = new ImageView(this);mConView.addView(imageView);imageView.setImageResource(R.drawable.specialadd);imageView.getLayoutParams().width = getResources().getDimensionPixelSize(R.dimen.dp_px_30);imageView.getLayoutParams().height = getResources().getDimensionPixelSize(R.dimen.dp_px_30);imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);imageView.setVisibility(View.VISIBLE);imageView.setX(startPosition[0]);imageView.setY(startPosition[1]);


Path path = new Path();path.moveTo(startPosition[0], startPosition[1]);path.quadTo(controlPosition[0], controlPosition[1], endPosition[0], endPosition[1]);PathMeasure pathMeasure = new PathMeasure();// false 表示 path 路径不闭合 pathMeasure.setPath(path, false);


// ofFloat 是一个生成器 ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, pathMeasure.getLength());// 匀速线性插值器 valueAnimator.setInterpolator(new LinearInterpolator());valueAnimator.setDuration(800);valueAnimator.addUpdateListener(animation -> {float value = (Float) animation.getAnimatedValue();pathMeasure.getPosTan(value, currentPosition, null);imageView.setX(currentPosition[0]);imageView.setY(currentPosition[1]);});valueAnimator.start();


ObjectAnimator shoppingCartX = ObjectAnimator.ofFloat(mShoppingCart, "scaleX", 1.0f, 1.3f, 1.0f);ObjectAnimator shoppingCartY = ObjectAnimator.ofFloat(mShoppingCart, "scaleY", 1.0f, 1.3f, 1.0f);shoppingCartX.setInterpolator(new AccelerateInterpolator());shoppingCartY.setInterpolator(new AccelerateInterpolator());AnimatorSet shoppingCart = new AnimatorSet();shoppingCart.play(shoppingCartX).with(shoppingCartY);shoppingCart.setDuration(800);shoppingCart.start();


valueAnimator.addListener(new Animator.AnimatorListener() {

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
使用二阶贝塞尔曲线实现添加购物车动画,移动互联网开发专业