通过自定义View与ViewGroup实现小米商城购物车效果

用到的知识点

  1. 自定义View
  2. 自定义ViewGroup
  3. 贝塞尔曲线

原理

  • 通过贝塞尔曲线实现商品抛入购物车的路径
  • 自定义ViewGroup实现添加多个商品进购物车的动画
  • 自定义View绘制心以及购物车图案

代码

一.绘制底部背景View

1.通过Path绘制第一部分,绘制心以及文字
通过贝赛尔曲线绘制心形

/*** 绘制喜欢** @param canvas* @param x* @param y*/private void drawLove(Canvas canvas, float x, float y) {canvas.save();canvas.translate(x, y);Path leftPath = new Path();leftPath.moveTo(0, -40);Path rightPath = new Path();rightPath.moveTo(0, -40);leftPath.cubicTo(0, -40, -30, -80, -35, -40);leftPath.cubicTo(-35, -40, -30, -30, 0, 10);rightPath.cubicTo(0, -40, 30, -80, 35, -40);rightPath.cubicTo(35, -40, 30, -30, 0, 10);if (isLove) {mLovePaint.setStyle(Paint.Style.FILL);mLovePaint.setColor(Color.RED);} else {mLovePaint.setStyle(Paint.Style.STROKE);mLovePaint.setColor(Color.BLACK);}mLovePaint.setStrokeWidth(3);canvas.drawPath(leftPath, mLovePaint);canvas.drawPath(rightPath, mLovePaint);canvas.restore();float measureText = mTextPaint.measureText("喜欢", 0, "喜欢".length());canvas.drawText("喜欢", x - measureText / 2, y + 50, mTextPaint);}

2.绘制购物车区域 绘制购物车图形以及文购物车文字
通过Path的拼接绘制购物车图形

 /*** 绘制购物车** @param canvas* @param x* @param y*/private void drawShoppingCart(Canvas canvas, float x, float y) {canvas.save();canvas.translate(x, y);Path mPath = new Path();mPath.moveTo(-40, -60);mPath.lineTo(-30, -60);mPath.lineTo(-20, 0);mPath.lineTo(20, 0);mPath.lineTo(30, -40);mPath.lineTo(-10, -40);Path mPath2 = new Path();mPath2.moveTo(-10, -25);mPath2.lineTo(10, -25);mShoppingCartPaint.setStyle(Paint.Style.STROKE);mShoppingCartPaint.setStrokeWidth(5);mShoppingCartPaint.setColor(Color.BLACK);canvas.drawPath(mPath, mShoppingCartPaint);canvas.drawPath(mPath2, mShoppingCartPaint);mShoppingCartPaint.setStyle(Paint.Style.FILL);canvas.drawCircle(-15, 10, 5, mShoppingCartPaint);canvas.drawCircle(15, 10, 5, mShoppingCartPaint);mShoppingCartPaint.setColor(Color.RED);canvas.drawCircle(30, -40, 20, mShoppingCartPaint);String strNum = mProductTotal + "";mTextPaint.setTextSize(20);mTextPaint.setColor(Color.WHITE);float strNumLength = mTextPaint.measureText(strNum, 0, strNum.length());Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();canvas.drawText(strNum, 30 - strNumLength / 2, -40 - (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.top, mTextPaint);canvas.restore();String str = "购物车";mTextPaint.setTextSize(30);mTextPaint.setColor(Color.BLACK);float measureText = mTextPaint.measureText(str, 0, str.length());canvas.drawText(str, x - measureText / 2, y + 50, mTextPaint);}

3.绘制加入购物车文字
通过FontMetrics实现文字在矩形中心居中对齐

/*** 绘制加入购物车购物车** @param canvas* @param x* @param y*/private void drawShoppingText(Canvas canvas, float x, float y) {String str = "加入购物车";TextPaint textPaint = new TextPaint();textPaint.setTextSize(50);float measureText = textPaint.measureText(str, 0, str.length());Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();float v = fontMetrics.bottom - fontMetrics.top;canvas.drawText(str, x - measureText / 2, y - v / 2 - fontMetrics.top, textPaint);}

二.绘制动画View

1.绘制商品图片在抛物线路径上,抛物线路径由贝塞尔曲线组成,通过不断的改变数值实现商品图片抛物线移动

/*** 绘制商品图片在抛物线路径上* @param canvas*/private void drawProductOnPath(Canvas canvas) {PointF mCurveStart = new PointF();//曲线开始的点PointF mCurveMiddle = new PointF();//曲线中间点PointF mCurveEnd = new PointF();//曲线结束的点mCurveStart.set(measuredWidth * 0.7f, measuredHeight - 85);mCurveMiddle.set(measuredWidth * 0.4f, 0);mCurveEnd.set(measuredWidth * 0.3f, measuredHeight - 85);Path mCurvePath = new Path();//移动曲线mCurvePath.moveTo(mCurveStart.x, mCurveStart.y);mCurvePath.cubicTo(mCurveStart.x, mCurveStart.y, mCurveMiddle.x, mCurveMiddle.y, mCurveEnd.x, mCurveEnd.y);PathMeasure pathMeasure = new PathMeasure();pathMeasure.setPath(mCurvePath, false);float[] pos = new float[2];pathMeasure.getPosTan(pathMeasure.getLength() * percent, pos, null);Matrix matrix = new Matrix();matrix.postTranslate(pos[0] - newBitmap.getWidth() / 2, pos[1] - newBitmap.getHeight() / 2);canvas.drawBitmap(newBitmap, matrix, mBitmapPaint);}

2.ValueAnimator 数值改变的同时从绘View,实现商品图片的抛入购物车的动画效果,当View添加的时候start此ValueAnimator

/*** 改变数值实现动画*/private void initAnimator() {valueAnimator = ValueAnimator.ofInt(ints);valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {int animatedValue = (int) animation.getAnimatedValue();percent = animatedValue / 100f;if (percent < 0.8) {int height = (int) (bitmapWidth * (1 - percent));int width = (int) (bitmapHeight * (1 - percent));if (width > 0 && height > 0) {newBitmap = scaleBitmap(bitmap, 1 - percent);}}invalidate();}});valueAnimator.addListener(new AnimatorListenerAdapter() {@Overridepublic void onAnimationEnd(Animator animation) {super.onAnimationEnd(animation);mBitmapPaint.setAlpha(0);}@Overridepublic void onAnimationStart(Animator animation) {super.onAnimationStart(animation);mBitmapPaint.setAlpha(255);}});valueAnimator.setDuration(500);valueAnimator.setInterpolator(new AccelerateInterpolator());}

自定义ViewGroup实现购物车效果

1.ViewGroup初始化的时候将底部背景View添加进ViewGroup并且Layout的在底部
2.当点击加入购物车时候,将动画View添加进此ViewGroup,并且启动动画绘制界面实现商品抛进购物车效果。

@Overridepublic void add(int mProductTotal) {if (shoppingCartListener != null) {shoppingCartListener.add(mProductTotal);}ShoppingAnimChildView shoppingAnimView = new ShoppingAnimChildView(getContext());if (mProductBitmap != null) {shoppingAnimView.setProductBitmap(mProductBitmap);}LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);addView(shoppingAnimView, layoutParams);requestLayout();shoppingAnimView.startAnim();}

详细代码见Github传送门
欢迎大家star,fork
有很多不足,望见谅

可以直接下载代码使用

使用方法如下

使用方法1.布局文件添加以下属性<com.yhongm.shoppingcart.ShoppingCartViewandroid:id="@+id/vg"android:layout_alignParentBottom="true"android:layout_width="match_parent"android:layout_height="300dp" />2.java方法:scvg.setProductBitmap(产品图片bitmap); 设置产品图片scvg.setShoppingCartListener(this); 设置点击监听

安卓自定义view仿小米商城购物车动画相关推荐

  1. android的动态tab,Android自定义view仿QQ的Tab按钮动画效果(示例代码)

    话不多说 先上效果图 实现其实很简单,先用两张图 一张是背景的图,一张是笑脸的图片,笑脸的图片是白色,可能看不出来.实现思路:主要是再触摸view的时候同时移动这两个图片,但是移动的距离不一样,造成的 ...

  2. Android仿支付宝UI功能开发,Android 自定义view仿支付宝咻一咻功能

    支付宝上有一个咻一咻的功能,就是点击图片后四周有水波纹的这种效果,今天也写一个类似的功能. 效果如下所示: 思路: 就是几个圆的半径不断在变大,这个可以使用动画缩放实现,还有透明动画 还有就是这是好几 ...

  3. 自定义View | 仿QQ运动步数进度效果

    项目GitHub地址 思路 固定不动的蓝色大圆弧 动画变动的红色小圆弧 中间的步数文字显示 相关的自定义属性 比如固定不动的大圆弧, 我们不能写死他的蓝色颜色属性, 要提供一个颜色的自定义属性给用户自 ...

  4. android 高仿 探探卡片滑动,Android自定义View仿探探卡片滑动效果

    Android自定义View仿探探卡片滑动这种效果网上有很多人已经讲解了实现思路,大多都用的是RecyclerView来实现的,但是我们今天来换一种实现思路,只用一个自定义的ViewGroup来搞定这 ...

  5. android wear支付宝6,Android自定义View仿支付宝输入六位密码功能

    跟选择银行卡界面类似,也是用一个PopupWindow,不过输入密码界面是一个自定义view,当输入六位密码完成后用回调在Activity中获取到输入的密码并以Toast显示密码.效果图如下: 自定义 ...

  6. 安卓自定义View实现加载gif图片

    开题:加载GIF的场景在安卓开发中还比较常见,网上也有一些三方法的框架会支持对gif的加载,在上篇博客为大家推荐的图片加载库Glide也支持gif的加载Glide工具类的简单封装,今天给大家分享通过自 ...

  7. 安卓自定义View进阶-事件分发机制原理

    之前讲解了很多与View绘图相关的知识,你可以在 安卓自定义View教程目录 中查看到这些文章,如果你理解了这些文章,那么至少2D绘图部分不是难题了,大部分的需求都能满足,但是关于View还有很多知识 ...

  8. android 自定义 对号,Android自定义View实现打钩动画功能

    先上效果图 动图 静态图 1. 回顾 [Android自定义View:一个精致的打钩小动画]上一篇文章,我们已经实现了基本上实现了控件的效果了,但是...但是...过了三四天后,仔细看回自己写的代码, ...

  9. 安卓自定义view全解:初始化,onDraw函数,onMeasure函数,用户手势事件

    全栈工程师开发手册 (作者:栾鹏) 安卓教程全解 安卓自定义view全解. view类包含如下函数.可供重写. onFinishInflate() 回调方法,当应用从XML加载该组件并用它构建界面之后 ...

最新文章

  1. 开启注解缓存_Spring Boot 2.x基础教程:进程内缓存的使用与Cache注解详解
  2. Java的poi的excel导入怎么判断日期格式的单元格
  3. tableView练习 -- QQ好友列表
  4. python 双向链表_Python实现双向链表
  5. NetBeans 7.1:创建自定义提示
  6. 【Linux系列】Linux基础知识整理
  7. Applying a Color Wash to Images
  8. java Socket实现简单在线聊天(二)
  9. 设置View的四个角为圆角
  10. bootstrapt学习指南_bootstrap-知识点梳理-学习入门篇
  11. 完了!Windows弱爆了!Linux才是程序员的首选!程序员:好用!
  12. SpringBoot系列之使用自定义注解校验用户是否登录
  13. 如何生成静态页面的五种方案
  14. 人教版四年级上次计算机教案,人教版四年级上册数学教案
  15. 谷歌浏览器设置信任_Win10谷歌浏览器添加信任网址/站点的方法
  16. windows 11激活Office提示网络问题无法激活
  17. C/C++编程学习 - 第5周 ⑤ 人见人爱A+B
  18. 【解决电脑】开机屏幕左键无反应,右键变加载;选择文件夹未响应,卡顿40秒后恢复;新建文件夹正常,删除移动卡顿
  19. 织梦模板建站教程:织梦根目录下文件是什么意思?
  20. UE5学习笔记(二)——3D材质蓝图的常用节点介绍

热门文章

  1. c语言getch退出程序,用getch()时怎么样清除输入缓冲
  2. 服务器启动成功网页无法访问,apache启动后无法访问网页的解决方法
  3. 同城跑腿微信小程序制作步骤_分享下同城跑腿小程序的作用
  4. poj1066 Jugs
  5. 记一次企业邮官网SEO优化
  6. MST++: Multi-stage Spectral-wiseTransformer for Efficient Spectral Reconstruction
  7. 原生js实现table 横向纵向全选功能
  8. 函数式思维: 运用函数式思维,第2 部分
  9. 计算机主板提示ahci,电脑BIOS没有AHCI功能没有办法BIOS刷新怎么办
  10. 【2021年最新版Java校招面试题目合集】