編輯:關於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,連續點擊動畫如何讓動畫不單例運行
最主要的問題我已經解決了,你只需要發揮想象創建更多的復雜炫酷的動畫。
很多Android系統手機都或多或少出現過信號不穩的問題,其實很多時候不是手機自身的質量不佳,而是我們沒有對其進行合理的網絡配置。以聯通WCDMA制式的An
多線程下載文件的過程是:(1)首先獲得下載文件的長度,然後設置本地文件的長度。HttpURLConnection.getContentLength();//獲取下載文件的
本文實例講述了Android之日期及時間選擇對話框用法。分享給大家供大家參考。具體如下:清單文件:<?xml version=1.0 encoding=ut
本例為模仿微信聊天界面UI設計,文字發送以及語言錄制UI。1先看效果圖: 第一:chat.xml設計 <?xml vers