Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android animation——添加購物車動畫(填坑和優化)

android animation——添加購物車動畫(填坑和優化)

編輯:關於Android編程

我們經常看到不管是某寶還是某東都有加入購物車的動畫。就是在點擊某個商品後,這個商品變成小的縮略圖移動到購物車裡面去。

今天突然想著把原來做過的這麼一個動畫貼出來供大家學習。

先看效果圖。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,連續點擊動畫如何讓動畫不單例運行

最主要的問題我已經解決了,你只需要發揮想象創建更多的復雜炫酷的動畫。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved