android animation——添加购物车动画(填坑和优化)

我们经常看到不管是某宝还是某东都有加入购物车的动画。就是在点击某个商品后,这个商品变成小的缩略图移动到购物车里面去。

今天突然想着把原来做过的这么一个动画贴出来供大家学习。

先看效果图。gif工具不忍直视,真实操作是很流畅的一个抛物线。

首先从效果图看出来我们需要几个东西。

1,动画的开始位置

2,动画的结束位置

3,动画移动的图片(这里为了简单用一个小圆点,可以换成商品的缩略图)

4,动画的弧度如何处理

5,动画完成后在哪里操作数据

6,连续点击图片动画时如何new出多个动画

那么我们就来解决这问题

首相定义一个ShoppingCartAnim类,定义几个必要常量

**
 * 购物车添加动画
 */
public class ShoppingCartAnim {
    private ImageView buyImg;//播放动画的参照imageview
    private int[] start_location = new int[2];// 这是用来存储动画开始位置的X、Y坐标;
    private int[] end_location = new int[2];// 这是用来存储动画结束位置的X、Y坐标;
    private static Handler mThreadHandler;//数据操作的非ui线程回调
    public ViewGroup root;//动画层
    private static Thread thread;//数据操作的非ui线程
   }

其中我定义了一个线程和一个handler,这样做的目的就是为了在动画结束后做一些操作不要影响下一次点击动画。所以放在非ui’线程中。

这样,当我们连续点击动画的时候,不会因为上一次的数据没有操作完而动画出现卡顿。

在静态方法中实例化子线程

static {
        thread = new Thread(new Runnable() {
            @Override
            public void run() {
                //非ui线程
                //这里执行动画完成后的数据处理,例如将商品加入购物车

                //发送消息给ui线程
                mThreadHandler.sendEmptyMessage(0);
            }
        });
        mThreadHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                switch (msg.what) {
                    case 0:
                    //线程操作完以后要及时关闭
                    thread.interrupt();
                        //ui操作
                        //这里做动画结束后的处理,例如购物车抖动动画
                        break;
                }
            }
        };

定义构造方法

public ShoppingCartAnim(Activity activity) {
        buyImg = new ImageView(activity);//buyImg是动画的图片
        buyImg.setImageResource(R.drawable.sign);// 设置buyImg的图片
        //buyImg.setImageBitmap(bitmap);//也可以设置bitmap,可以用商品缩略图来播放动画
        root = (ViewGroup) activity.getWindow().getDecorView();//创建一个动画层
        root.addView(buyImg);//将动画参照imageview放入
    }

定义将imageview放到动画层并放在起始坐标位置的方法

    /**
     * 将image图片添加到动画层并放在起始坐标位置
     *
     * @param view     播放动画的view
     * @param location 起始位置
     * @return
     */
    private View addViewFromAnimLayout(View view, int[] location) {
        int x = location[0];
        int y = location[1];
        FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
                FrameLayout.LayoutParams.WRAP_CONTENT,
                FrameLayout.LayoutParams.WRAP_CONTENT);
        lp.leftMargin = x;
        lp.topMargin = y;
        view.setLayoutParams(lp);
        return view;
    }

我们将一个需要播放的imageview和起始坐标传入,就得到了这个imageview的具体起始位置,播放动画的时候就可以直接拿来用了。因为位置的问题已经在其中调整好了。

最重要的部分

提供一个外界调用的接口,传入动画的起始参照目标和结束参照目标

public void startAnim(View startView, View endView) {
        // 这是获取起始目标view在屏幕的X、Y坐标(这也是动画开始的坐标)
        startView.getLocationInWindow(start_location);
        // 购物车结束位置
        endView.getLocationInWindow(end_location);
        //将动画图片和起始坐标绘制成新的view,用于播放动画
        //将image图片添加到动画层
        /**这里为什么不直接传一个图片而是传一个imageview呢?
         * 因为我这样做的目的是clone动画播放控件,为什么要clone呢?
         * 因为如果用户连续点击添加购物车的话,如果只用一个imageview去播放动画的话,这个动画就会成还没播放完就回到原点重新播放。
         * 而如果clone一个imageview去播放,那么这个动画还没播放完,用户再点击添加购物车以后我们还是clone一个新的imageview去播放。
         * 这样动画就会出现好几个点而不是一个点还没播放完又缩回去。
         * 说的通俗点,就是依靠这个方法,把参照对象和起始位置穿进去,得到一个clone的对象来播放动画
         */View run_view = addViewFromAnimLayout(buyImg, start_location);

        // 计算位移
        int endX = end_location[0] - start_location[0];
        int endY = end_location[1] - start_location[1];

        //平移动画 绘制X轴 0到结束的x轴
        TranslateAnimation translateAnimationX = new TranslateAnimation(0,
                endX, 0, 0);
        //设置线性插值器
        translateAnimationX.setInterpolator(new LinearInterpolator());
        // 动画重复执行的次数
        translateAnimationX.setRepeatCount(0);
        //设置动画播放完以后消失,终止填充
        translateAnimationX.setFillAfter(true);

        //平移动画 绘制Y轴
        TranslateAnimation translateAnimationY = new TranslateAnimation(0, 0,
                0, endY);
        translateAnimationY.setInterpolator(new AccelerateInterpolator());
        translateAnimationY.setRepeatCount(0);
        translateAnimationX.setFillAfter(true);

        //将两个动画放在动画播放集合里
        // 设置false使每个子动画都使用自己的插值器
        AnimationSet set = new AnimationSet(false);
        //设置动画播放完以后消失,终止填充
        set.setFillAfter(false);
        set.addAnimation(translateAnimationY);
        set.addAnimation(translateAnimationX);
        set.setDuration(800);// 动画的执行时间
        /**
         * 动画开始播放的时候,参照对象要显示出来,如果不显示的话这个动画会看不到任何东西。
         * 因为不管用户点击几次动画,播放的imageview都是从参照对象buyImg中clone来的
         * */
        buyImg.setVisibility(View.VISIBLE);
        run_view.startAnimation(set);
        // 动画监听事件
        set.setAnimationListener(new Animation.AnimationListener() {
            // 动画的开始
            @Override
            public void onAnimationStart(Animation animation) {

            }

            //动画重复中
            @Override
            public void onAnimationRepeat(Animation animation) {
                // TODO Auto-generated method stub
            }

            // 动画的结束
            @Override
            public void onAnimationEnd(Animation animation) {
                //动画播放完以后,参照对象要隐藏
                buyImg.setVisibility(View.GONE);
                //结束后访问数据
                thread.start();
            }
        });
    }

每一句代码我都解释的很详细了。

你也可以在动画集合中加入旋转缩放什么的,也是很简单的。

还有一个细节操作,这个操作在activity中:

    /**
     * 内存过低时及时处理动画产生的未处理冗余tg
     */
    @Override
    public void onLowMemory() {
        // TODO Auto-generated method stub
        if (cartAnimation != null) {
            try {
                cartAnimation.root.removeAllViews();
            } catch (Exception e) {
                e.printStackTrace();
            }
            super.onLowMemory();
        }
    }

主要部分已经完成了。

看看怎么调用。

CartAnimation cartAnimation = new CartAnimation(getActivity());
            cartAnimation.setAnim(startImageview, shoppingCartView);

不需要任何的返回值,你需要操作数据完全可以在线程中操作。

好了,这就是添加购物车动画,你可以在这之上发挥想象添加更加炫酷的动画。

不过还是总结一下细节。(嗯,细节很重要!)

1,动画的播放依据是activity,如何考虑内存消耗问题

2,动画播放完以后如何操作数据才能让动画不卡顿

3,连续点击动画如何让动画不单例运行

最主要的问题我已经解决了,你只需要发挥想象创建更多的复杂炫酷的动画。

时间: 2024-10-19 13:54:50

android animation——添加购物车动画(填坑和优化)的相关文章

Android 实现蘑菇街购物车动画效果

版本:1.0 日期:2014.8.6 版权:© 2014 kince 转载注明出处 使用过蘑菇街的用户基本上都知道有一个加入购物车的动画效果,此处不具体描述想知道的可以去下载体验一下. 1.思路 目前想到两种方式实现这种效果,一是使用Tween动画,直截了当的进行一个移动,蘑菇街就是使用这样的方法.二是使用WindowManager创建一个View,然后对这个View进行移动. 2.实现 本文先用方式一方法实现,之后会用方式二方法实现. 方式一: Activity代码: package com.

【转】Android 实现蘑菇街购物车动画效果

原文出处:http://blog.csdn.net/wangjinyu501/article/details/38400479 1.思路 目前想到两种方式实现这种效果,一是使用Tween动画,直截了当的进行一个移动,蘑菇街就是使用这样的方法.二是使用WindowManager创建一个View,然后对这个View进行移动. 2.实现 本文先用方式一方法实现,之后会用方式二方法实现. 方式一: Activity代码: 1 package com.kince.mogujie; 2 3 import a

android调用微信支付,填坑

关于android调用微信支付,在网上基本是骂声一片.在于官方文档,对于许多问题都没有描述.我罗列一下我遇到的麻烦,供大家参考 首先想要获取微信支付功能,必须在微信开放平台,申请app 支付能力,根据官方文档,按照要求,完成后 官方会提供 appid .appsercert两个重要参数.以及自己设置的应用签名 一:官方文档 https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_1 根据官方文档,app需要先调用预支付接口获得 p

添加购物车动画

#import "Solo_Cart_Methon.h" #define Screen_W [UIScreen mainScreen].bounds.size.width #define Screen_H [UIScreen mainScreen].bounds.size.height @interface Solo_Cart_Methon() { CALayer *_layer; } @property(nonatomic,strong)CALayer *layer; @proper

android——activity添加退出动画

在finish()语句后加 //该方法的参数:前者是将要进入activity的进入动画,后者是正要退出activity的动画 overridePendingTransition(R.anim.abc_fade_in,R.anim.login_activity_out); 2.特别注意两个动画的时间要一致:

Android WebView填坑记录

前言 在应用程序开发过程中,经常会采用webview来展现某些界面,这样就可以不受发布版本控制,实时更新,遇到问题可以快速修复. 但是在Android开发中,由于Android版本分化严重,每一个版本针对webview都有部分更改,因此在开发过程中会遇到各种各样的坑,因此在此总结一下在开发过程中遇到的一些坑! 样例 这里不是讲解怎么进行webview开发,而是只罗列其中遇到的一些坑!为了展示这些问题,我们还是写一个样例来进行展开. 样例代码: /** * WebView demo */ publ

Android学习之 属性动画<Property Animation>

property 动画系统是相当健壮的框架,它几乎可以动画显示任何对象. 你可以定义一个动画来定时改变任何对象的属性值,不论该对象是否在屏幕上显示. property 动画将以一定的时间间隔修改属性值(对象中的字段值). 要实现动画显示,你须指定对象的相应属性(比如对象的屏幕位置),以及动画时长.动画时间间隔. property 动画系统能让你设定以下动画要素: 1.持续时间:指定动画的持续显示时间.默认的时长是300毫秒. 2.插值因子:指定属性值的变化方式,表示为关于动画已显示时间的函数.

Android Animation 动画Demo(Frame逐帧动画)

上一篇介绍了Animation动画其一:Tween补间动画. 这篇文章接下来介绍Animation另一种动画形式:Frame逐帧动画. Frame动画是一系列图片按照一定的顺序展示的过程,和放电影的机制很相似,我们称为逐帧动画.Frame动画可以被定义在XML文件中,也可以完全编码实现(后面会给出这两种实现方式的源代码Demo). 下面分别介绍: 一.定义在xml中实现: 实现效果图: 源代码: 布局文件:main.xml: <?xml version="1.0" encodin

Android(java)学习笔记263:Android下的属性动画(Property Animation)

1. 属性动画(Property Animation)引入: 在手机上去实现一些动画效果算是件比较炫酷的事情,因此Android系统在一开始的时候就给我们提供了两种实现动画效果的方式,逐帧动画(frame-by-frame animation)和补间动画(tweened animation). 逐帧动画的工作原理很简单,其实就是将一个完整的动画拆分成一张张单独的图片,然后再将它们连贯起来进行播放,类似于动画片的工作原理. 补间动画则是可以对View进行一系列的动画操作,包括淡入淡出.缩放.平移.