安卓自定义view仿小米商城购物车动画
2017-06-08 17:02
288 查看
通过自定义View与ViewGroup实现小米商城购物车效果
![](https://img-blog.csdn.net/20170608160838119?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveXVob25nbWlhbzUyMQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
自定义ViewGroup
贝塞尔曲线
自定义ViewGroup实现添加多个商品进购物车的动画
自定义View绘制心以及购物车图案
通过贝赛尔曲线绘制心形
2.绘制购物车区域 绘制购物车图形以及文购物车文字
通过Path的拼接绘制购物车图形
3.绘制加入购物车文字
通过FontMetrics实现文字在矩形中心居中对齐
2.ValueAnimator 数值改变的同时从绘View,实现商品图片的抛入购物车的动画效果,当View添加的时候start此ValueAnimator
2.当点击加入购物车时候,将动画View添加进此ViewGroup,并且启动动画绘制界面实现商品抛进购物车效果。
详细代码见Github传送门
欢迎大家star,fork
有很多不足,望见谅
用到的知识点
自定义View自定义ViewGroup
贝塞尔曲线
原理
通过贝塞尔曲线实现商品抛入购物车的路径自定义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() { @Override public 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() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); mBitmapPaint.setAlpha(0); } @Override public 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,并且启动动画绘制界面实现商品抛进购物车效果。
@Override public void add(int mProductTotal) { if (shoppingCartListener != 9558 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.ShoppingCartView android:id="@+id/vg" android:layout_alignParentBottom="true" android:layout_width="match_parent" android:layout_height="300dp" /> 2.java方法: scvg.setProductBitmap(产品图片bitmap); 设置产品图片 scvg.setShoppingCartListener(this); 设置点击监听
相关文章推荐
- android自定义TextView实现安卓手机开机android文字Log的动画效果
- 安卓自定义View——(一:RaiseNumberAnimTextView 带数字增长动画的TextView)
- 安卓自定义view动画案例
- 安卓开发之自定义动画控件BatteryView(电池加载动画)
- Android自定义view-高仿小米视频加载动画效果
- 安卓自定义view,实现页面切换的位置指示动画
- 【安卓开机动画】小米正在排队,请…
- 自定义push viewcontroll 的动画 (Custom animation for pushing a UIViewController)
- pushViewController自定义动画(转)
- (转)android 自定义ViewGroup和对view进行切图动画实现滑动菜单SlidingMenu
- 【安卓开机动画】小米正在排队,请…
- android 自定义ViewGroup和对view进行切图动画实现滑动菜单SlidingMenu[转]
- 安卓开发28:自定义View类
- 自定义view中绘制动画
- android 自定义ViewGroup和对view进行切图动画实现滑动菜单SlidingMenu
- 【安卓开机动画】小米正在排队,请…
- IOS 自定义presentModalViewController动画
- android 自定义ViewGroup和对view进行切图动画实现滑动菜单SlidingMenu
- 自定义view中绘制动画
- android 自定义ViewGroup和对view进行切图动画实现滑动菜单SlidingMenu