一、引入
在绥化等地区,都构建了全面的区域性战略布局,加强发展的系统性、市场前瞻性、产品创新能力,以专注、极致的服务理念,为客户提供成都网站建设、做网站 网站设计制作按需设计网站,公司网站建设,企业网站建设,品牌网站设计,营销型网站建设,外贸网站制作,绥化网站建设费用合理。
二、大致思路
1、如图所示主要有三个点,起点、终点、以及贝塞尔曲线的控制点
2、起点即点击的View的位置,一般来说用如下方式即可取得。startPosition[0]为x轴开始坐标,startPosition[1]为Y轴终点坐标,两点可以看作对角线上面的两个端点(左上角x坐标,右下角y坐标)
//贝塞尔起始数据点 int[] startPosition = new int[2]; view.getLocationOnScreen(startPosition);
3、终点即购物车篮子的位置,与起点类似
mShoppingCart.getLocationInWindow(endPosition);
4、控制点,我选的控制点为上图的C点,即A点的y坐标,B点的X坐标
controlPosition[0] = endPosition[0]; controlPosition[1] = startPosition[1];
5、需要注意的地方,我不清楚是不是因为我的布局的问题,获取到的点击的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];
6、通过Path的quadTo方法绘制贝塞尔曲线,使用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是一个生成器 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();
7、下面是用属性动画给购物车篮子做了一个放大缩小的动画效果
// mShoppingCart是View 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();
三、稍完整的大部分代码
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() { @Override public void onAnimationStart(Animator animation) { } //当动画结束后: @Override public void onAnimationEnd(Animator animation) { goodsChange(data); } @Override public void onAnimationCancel(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } }); }
四、大致写下布局(同时也算留做备份)
<?xml version="1.0" encoding="utf-8"?>顶部常驻的toolbar TabLayout上面的View 最下面的购物车一栏
五、推荐资源
View的位置参数
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对创新互联的支持。