当我们写商城类的项目的时候,一般都会有加入购物车的功能,加入购物车的时候会有一些抛物线动画,具体代码如下:
实现效果如图:
思路:
确定动画的起终点 在起终点之间使用二次贝塞尔曲线填充起终点之间的点的轨迹 设置属性动画,ValueAnimator插值器,获取中间点的坐标 将执行动画的控件的x、y坐标设为上面得到的中间点坐标 开启属性动画 当动画结束时的 *** 作难点:
PathMeasure的使用
- getLength()
- boolean getPosTan(float distance,float[] pos,float[] tan) 的理解
涉及到的知识点:
如何获取控件在屏幕中的绝对坐标
//得到父布局的起始点坐标(用于辅助计算动画开始/结束时的点的坐标) int[] parentLocation = new int[2]; rl.getLocationInWindow(parentLocation);
如何使用贝塞尔曲线以及属性动画插值器ValueAnimator
// 四、计算中间动画的插值坐标(贝塞尔曲线)(其实就是用贝塞尔曲线来完成起终点的过程) //开始绘制贝塞尔曲线 Path path = new Path(); //移动到起始点(贝塞尔曲线的起点) path.moveto(startX,startY); //使用二次萨贝尔曲线:注意第一个起始坐标越大,贝塞尔曲线的横向距离就会越大,一般按照下面的式子取即可 path.quadTo((startX + toX) / 2,startY,toX,toY); //mPathMeasure用来计算贝塞尔曲线的曲线长度和贝塞尔曲线中间插值的坐标, // 如果是true,path会形成一个闭环 mPathMeasure = new PathMeasure(path,false); //★★★属性动画实现(从0到贝塞尔曲线的长度之间进行插值计算,获取中间过程的距离值) ValueAnimator valueAnimator = ValueAnimator.offloat(0,mPathMeasure.getLength()); valueAnimator.setDuration(1000); // 匀速线性插值器 valueAnimator.setInterpolator(new linearInterpolator()); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @OverrIDe public voID onAnimationUpdate(ValueAnimator animation) { // 当插值计算进行时,获取中间的每个值, // 这里这个值是中间过程中的曲线长度(下面根据这个值来得出中间点的坐标值) float value = (float) animation.getAnimatedValue(); // ★★★★★获取当前点坐标封装到mCurrentposition // boolean getPosTan(float distance,float[] tan) : // 传入一个距离distance(0<=distance<=getLength()),然后会计算当前距 // 离的坐标点和切线,pos会自动填充上坐标,这个方法很重要。 mPathMeasure.getPosTan(value,mCurrentposition,null);//mCurrentposition此时就是中间距离点的坐标值 // 移动的商品图片(动画图片)的坐标设置为该中间点的坐标 goods.setTranslationX(mCurrentposition[0]); goods.setTranslationY(mCurrentposition[1]); } });// 五、 开始执行动画 valueAnimator.start();
所有代码:
package cn.c.com.bezIErcurveanimater;@R_301_5565@ androID.animation.Animator;@R_301_5565@ androID.animation.ValueAnimator;@R_301_5565@ androID.graphics.Bitmap;@R_301_5565@ androID.graphics.BitmapFactory;@R_301_5565@ androID.graphics.Path;@R_301_5565@ androID.graphics.PathMeasure;@R_301_5565@ androID.os.Bundle;@R_301_5565@ androID.support.v7.app.AppCompatActivity;@R_301_5565@ androID.support.v7.Widget.linearlayoutmanager;@R_301_5565@ androID.support.v7.Widget.RecyclerVIEw;@R_301_5565@ androID.vIEw.LayoutInflater;@R_301_5565@ androID.vIEw.VIEw;@R_301_5565@ androID.vIEw.VIEwGroup;@R_301_5565@ androID.vIEw.animation.linearInterpolator;@R_301_5565@ androID.Widget.ImageVIEw;@R_301_5565@ androID.Widget.relativeLayout;@R_301_5565@ androID.Widget.TextVIEw;@R_301_5565@ java.util.ArrayList;public class MainActivity extends AppCompatActivity { private RecyclerVIEw mRecyclerVIEw; private ImageVIEw cart; private ArrayList<Bitmap> bitmapList = new ArrayList<>(); private relativeLayout rl; private PathMeasure mPathMeasure; /** * 贝塞尔曲线中间过程的点的坐标 */ private float[] mCurrentposition = new float[2]; private TextVIEw count; private int i = 0; @OverrIDe protected voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentVIEw(R.layout.activity_main); initVIEw(); initimg(); MyAdapter myAdapter = new MyAdapter(bitmapList); mRecyclerVIEw.setAdapter(myAdapter); mRecyclerVIEw.setLayoutManager(new linearlayoutmanager(MainActivity.this)); } private voID initimg() { bitmapList.add(BitmapFactory.decodeResource(getResources(),R.drawable.coin)); bitmapList.add(BitmapFactory.decodeResource(getResources(),R.drawable.coin1)); bitmapList.add(BitmapFactory.decodeResource(getResources(),R.drawable.coin91)); } private voID initVIEw() { mRecyclerVIEw = (RecyclerVIEw) findVIEwByID(R.ID.recyclerVIEw); cart = (ImageVIEw) findVIEwByID(R.ID.cart); rl = (relativeLayout) findVIEwByID(R.ID.rl); count = (TextVIEw) findVIEwByID(R.ID.count); } class MyAdapter extends RecyclerVIEw.Adapter<MyVH> { private ArrayList<Bitmap> bitmapList; public MyAdapter(ArrayList<Bitmap> bitmapList) { this.bitmapList = bitmapList; } @OverrIDe public MyVH onCreateVIEwHolder(VIEwGroup parent,int vIEwType) { LayoutInflater inflater = LayoutInflater.from(MainActivity.this); VIEw itemVIEw = inflater.inflate(R.layout.item,parent,false); MyVH myVH = new MyVH(itemVIEw); return myVH; } @OverrIDe public voID onBindVIEwHolder(final MyVH holder,final int position) { holder.iv.setimageBitmap(bitmapList.get(position)); holder.buy.setonClickListener(new VIEw.OnClickListener() { @OverrIDe public voID onClick(VIEw v) { addCart(holder.iv); } }); } @OverrIDe public int getItemCount() { return bitmapList.size(); } } /** * ★★★★★把商品添加到购物车的动画效果★★★★★ * @param iv */ private voID addCart( ImageVIEw iv) {// 一、创造出执行动画的主题---imagevIEw //代码new一个imagevIEw,图片资源是上面的imagevIEw的图片 // (这个图片就是执行动画的图片,从开始位置出发,经过一个抛物线(贝塞尔曲线),移动到购物车里) final ImageVIEw goods = new ImageVIEw(MainActivity.this); goods.setimageDrawable(iv.getDrawable()); relativeLayout.LayoutParams params = new relativeLayout.LayoutParams(100,100); rl.addVIEw(goods,params);// 二、计算动画开始/结束点的坐标的准备工作 //得到父布局的起始点坐标(用于辅助计算动画开始/结束时的点的坐标) int[] parentLocation = new int[2]; rl.getLocationInWindow(parentLocation); //得到商品图片的坐标(用于计算动画开始的坐标) int startLoc[] = new int[2]; iv.getLocationInWindow(startLoc); //得到购物车图片的坐标(用于计算动画结束后的坐标) int endLoc[] = new int[2]; cart.getLocationInWindow(endLoc);// 三、正式开始计算动画开始/结束的坐标 //开始掉落的商品的起始点:商品起始点-父布局起始点+该商品图片的一半 float startX = startLoc[0] - parentLocation[0] + iv.getWIDth() / 2; float startY = startLoc[1] - parentLocation[1] + iv.getHeight() / 2; //商品掉落后的终点坐标:购物车起始点-父布局起始点+购物车图片的1/5 float toX = endLoc[0] - parentLocation[0] + cart.getWIDth() / 5; float toY = endLoc[1] - parentLocation[1];// 四、计算中间动画的插值坐标(贝塞尔曲线)(其实就是用贝塞尔曲线来完成起终点的过程) //开始绘制贝塞尔曲线 Path path = new Path(); //移动到起始点(贝塞尔曲线的起点) path.moveto(startX,null);//mCurrentposition此时就是中间距离点的坐标值 // 移动的商品图片(动画图片)的坐标设置为该中间点的坐标 goods.setTranslationX(mCurrentposition[0]); goods.setTranslationY(mCurrentposition[1]); } });// 五、 开始执行动画 valueAnimator.start();// 六、动画结束后的处理 valueAnimator.addListener(new Animator.AnimatorListener() { @OverrIDe public voID onAnimationStart(Animator animation) { } //当动画结束后: @OverrIDe public voID onAnimationEnd(Animator animation) { // 购物车的数量加1 i++; count.setText(String.valueOf(i)); // 把移动的图片imagevIEw从父布局里移除 rl.removeVIEw(goods); } @OverrIDe public voID onAnimationCancel(Animator animation) { } @OverrIDe public voID onAnimationRepeat(Animator animation) { } }); } class MyVH extends RecyclerVIEw.VIEwHolder { private ImageVIEw iv; private TextVIEw buy; public MyVH(VIEw itemVIEw) { super(itemVIEw); iv = (ImageVIEw) itemVIEw.findVIEwByID(R.ID.iv); buy = (TextVIEw) itemVIEw.findVIEwByID(R.ID.buy); } }}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。
总结以上是内存溢出为你收集整理的Android把商品添加到购物车的动画效果(贝塞尔曲线)全部内容,希望文章能够帮你解决Android把商品添加到购物车的动画效果(贝塞尔曲线)所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)