Android 使用NineOldAndroids實現絢麗的ListView左右滑動刪除Item效果

轉載請註明出處:http://blog.csdn.net/xiaanming/article/details/18311877

轉載請註明本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/18311877),請尊重他人的辛勤勞動成果,謝謝!

今天還是給大家帶來自定義控件的編寫,自定義一個ListView的左右滑動刪除Item的效果,這個效果之前已經實現過了,有興趣的可以看下Android 使用Scroller實現絢麗的ListView左右滑動刪除Item效果,之前使用的是滑動類Scroller來實現的,但是看了下通知欄的左右滑動刪除效果,確實很棒,當我們滑動Item超過一半的時候,item的透明度就變成了0,我們就知道擡起手指的時候item就被刪除了,當item的透明度不爲0的時候,我們擡起手指Item會回到起始位置,這樣我們就知道拖動到什麼位置item會刪除,什麼位置Item不刪除,用戶體驗更好了,還有一個效果,就是我們滑動刪除了item的時候,ListView的其他item會出現向上或者向下滾動的效果,感覺效果很棒,所以在GitHub上面搜索了下,發現很多開源庫都有這個效果,比如ListViewAnimationsandroid-swipelistview等等,我看了下實現原理,使用的是Jake Wharton的動畫開源庫NineOldAndroids,這個庫究竟是幹嘛的呢?在API3.0(Honeycomb), SDK新增了一個android.animation包,裏面的類是實現動畫效果相關的類,通過Honeycomb API,能夠實現非常複雜的動畫效果,但是如果開發者想在3.0以下使用這一套API, 則需要使用開源框架Nine Old Androids,在這個庫中會根據我們運行的機器判斷其SDK版本,如果是API3.0以上則使用Android自帶的動畫類,否則就使用Nine Old Androids庫中,這是一個兼容庫,接下來我們就來看看這個效果的具體實現吧

實現該效果的主要思路

  1. 先根據手指觸摸的點來獲取點擊的是ListView的哪一個Item
  2. 當手指在屏幕上面滑動的時候,我們要使得Item跟隨手指的滑動而滑動
  3. 當我們擡起手指的時候,我們根據滑動的距離或者手指在屏幕上面的速度來判斷Item是滑出屏幕還是滑動至其實位置
  4. Item滑出屏幕時,使ListView的其他item產生向上擠壓或者向下擠壓的效果

大致的思路這是這四步,其中的一些細節接下來我會一一爲大家解答的,接下來我們就用代碼來實現這種效果吧

首先我們新建一個工程,叫Swipedismisslistview,我們需要將Nine Old Androids這個庫引入到工程,大家可以去https://github.com/JakeWharton/NineOldAndroids下載,可以使用Jar包,也可以使用工程庫的形式引入到我們自己的工程,我們還需要自定義一個ListView,我們先看代碼然後給大家講解下具體的功能實現

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. package com.example.swipedismisslistview;  
  2.   
  3. import static com.nineoldandroids.view.ViewHelper.setAlpha;  
  4. import static com.nineoldandroids.view.ViewHelper.setTranslationX;  
  5. import android.content.Context;  
  6. import android.util.AttributeSet;  
  7. import android.view.MotionEvent;  
  8. import android.view.VelocityTracker;  
  9. import android.view.View;  
  10. import android.view.ViewConfiguration;  
  11. import android.view.ViewGroup;  
  12. import android.widget.AdapterView;  
  13. import android.widget.ListView;  
  14.   
  15. import com.nineoldandroids.animation.Animator;  
  16. import com.nineoldandroids.animation.AnimatorListenerAdapter;  
  17. import com.nineoldandroids.animation.ValueAnimator;  
  18. import com.nineoldandroids.view.ViewHelper;  
  19. import com.nineoldandroids.view.ViewPropertyAnimator;  
  20. /** 
  21.  * @blog http://blog.csdn.net/xiaanming 
  22.  *  
  23.  * @author xiaanming 
  24.  * 
  25.  */  
  26. public class SwipeDismissListView extends ListView {  
  27.     /** 
  28.      * 認爲是用戶滑動的最小距離 
  29.      */  
  30.     private int mSlop;  
  31.     /** 
  32.      * 滑動的最小速度 
  33.      */  
  34.     private int mMinFlingVelocity;  
  35.     /** 
  36.      * 滑動的最大速度 
  37.      */  
  38.     private int mMaxFlingVelocity;  
  39.     /** 
  40.      * 執行動畫的時間 
  41.      */  
  42.     protected long mAnimationTime = 150;  
  43.     /** 
  44.      * 用來標記用戶是否正在滑動中 
  45.      */  
  46.     private boolean mSwiping;  
  47.     /** 
  48.      * 滑動速度檢測類 
  49.      */  
  50.     private VelocityTracker mVelocityTracker;  
  51.     /** 
  52.      * 手指按下的position 
  53.      */  
  54.     private int mDownPosition;  
  55.     /** 
  56.      * 按下的item對應的View 
  57.      */  
  58.     private View mDownView;  
  59.     private float mDownX;  
  60.     private float mDownY;  
  61.     /** 
  62.      * item的寬度 
  63.      */  
  64.     private int mViewWidth;  
  65.     /** 
  66.      * 當ListView的Item滑出界面回調的接口 
  67.      */  
  68.     private OnDismissCallback onDismissCallback;  
  69.   
  70.     /** 
  71.      * 設置動畫時間 
  72.      *  
  73.      * @param mAnimationTime 
  74.      */  
  75.     public void setmAnimationTime(long mAnimationTime) {  
  76.         this.mAnimationTime = mAnimationTime;  
  77.     }  
  78.   
  79.     /** 
  80.      * 設置刪除回調接口 
  81.      *  
  82.      * @param onDismissCallback 
  83.      */  
  84.     public void setOnDismissCallback(OnDismissCallback onDismissCallback) {  
  85.         this.onDismissCallback = onDismissCallback;  
  86.     }  
  87.   
  88.     public SwipeDismissListView(Context context) {  
  89.         this(context, null);  
  90.     }  
  91.   
  92.     public SwipeDismissListView(Context context, AttributeSet attrs) {  
  93.         this(context, attrs, 0);  
  94.     }  
  95.   
  96.     public SwipeDismissListView(Context context, AttributeSet attrs,  
  97.             int defStyle) {  
  98.         super(context, attrs, defStyle);  
  99.   
  100.         ViewConfiguration vc = ViewConfiguration.get(context);  
  101.         mSlop = vc.getScaledTouchSlop();  
  102.         mMinFlingVelocity = vc.getScaledMinimumFlingVelocity() * 8//獲取滑動的最小速度  
  103.         mMaxFlingVelocity = vc.getScaledMaximumFlingVelocity();  //獲取滑動的最大速度  
  104.     }  
  105.   
  106.       
  107.     @Override  
  108.     public boolean onTouchEvent(MotionEvent ev) {  
  109.         switch (ev.getAction()) {  
  110.         case MotionEvent.ACTION_DOWN:  
  111.             handleActionDown(ev);  
  112.             break;  
  113.         case MotionEvent.ACTION_MOVE:  
  114.             return handleActionMove(ev);  
  115.         case MotionEvent.ACTION_UP:  
  116.             handleActionUp(ev);  
  117.             break;  
  118.         }  
  119.         return super.onTouchEvent(ev);  
  120.     }  
  121.   
  122.     /** 
  123.      * 按下事件處理 
  124.      *  
  125.      * @param ev 
  126.      * @return 
  127.      */  
  128.     private void handleActionDown(MotionEvent ev) {  
  129.         mDownX = ev.getX();  
  130.         mDownY = ev.getY();  
  131.           
  132.         mDownPosition = pointToPosition((int) mDownX, (int) mDownY);  
  133.   
  134.         if (mDownPosition == AdapterView.INVALID_POSITION) {  
  135.             return;  
  136.         }  
  137.   
  138.         mDownView = getChildAt(mDownPosition - getFirstVisiblePosition());  
  139.   
  140.         if (mDownView != null) {  
  141.             mViewWidth = mDownView.getWidth();  
  142.         }  
  143.   
  144.         //加入速度檢測  
  145.         mVelocityTracker = VelocityTracker.obtain();  
  146.         mVelocityTracker.addMovement(ev);  
  147.     }  
  148.       
  149.   
  150.     /** 
  151.      * 處理手指滑動的方法 
  152.      *  
  153.      * @param ev 
  154.      * @return 
  155.      */  
  156.     private boolean handleActionMove(MotionEvent ev) {  
  157.         if (mVelocityTracker == null || mDownView == null) {  
  158.             return super.onTouchEvent(ev);  
  159.         }  
  160.   
  161.         // 獲取X方向滑動的距離  
  162.         float deltaX = ev.getX() - mDownX;  
  163.         float deltaY = ev.getY() - mDownY;  
  164.   
  165.         // X方向滑動的距離大於mSlop並且Y方向滑動的距離小於mSlop,表示可以滑動  
  166.         if (Math.abs(deltaX) > mSlop && Math.abs(deltaY) < mSlop) {  
  167.             mSwiping = true;  
  168.               
  169.             //當手指滑動item,取消item的點擊事件,不然我們滑動Item也伴隨着item點擊事件的發生  
  170.             MotionEvent cancelEvent = MotionEvent.obtain(ev);  
  171.             cancelEvent.setAction(MotionEvent.ACTION_CANCEL |  
  172.                        (ev.getActionIndex()<< MotionEvent.ACTION_POINTER_INDEX_SHIFT));  
  173.             onTouchEvent(cancelEvent);  
  174.         }  
  175.   
  176.         if (mSwiping) {  
  177.             // 跟誰手指移動item  
  178.             ViewHelper.setTranslationX(mDownView, deltaX);  
  179.             // 透明度漸變  
  180.             ViewHelper.setAlpha(mDownView, Math.max(0f, Math.min(1f, 1f - 2f * Math.abs(deltaX)/ mViewWidth)));  
  181.   
  182.             // 手指滑動的時候,返回true,表示SwipeDismissListView自己處理onTouchEvent,其他的就交給父類來處理  
  183.             return true;  
  184.         }  
  185.   
  186.         return super.onTouchEvent(ev);  
  187.   
  188.     }  
  189.   
  190.     /** 
  191.      * 手指擡起的事件處理 
  192.      * @param ev 
  193.      */  
  194.     private void handleActionUp(MotionEvent ev) {  
  195.         if (mVelocityTracker == null || mDownView == null|| !mSwiping) {  
  196.             return;  
  197.         }  
  198.   
  199.         float deltaX = ev.getX() - mDownX;  
  200.           
  201.         //通過滑動的距離計算出X,Y方向的速度  
  202.         mVelocityTracker.computeCurrentVelocity(1000);  
  203.         float velocityX = Math.abs(mVelocityTracker.getXVelocity());  
  204.         float velocityY = Math.abs(mVelocityTracker.getYVelocity());  
  205.           
  206.         boolean dismiss = false//item是否要滑出屏幕  
  207.         boolean dismissRight = false;//是否往右邊刪除  
  208.           
  209.         //當拖動item的距離大於item的一半,item滑出屏幕  
  210.         if (Math.abs(deltaX) > mViewWidth / 2) {  
  211.             dismiss = true;  
  212.             dismissRight = deltaX > 0;  
  213.               
  214.             //手指在屏幕滑動的速度在某個範圍內,也使得item滑出屏幕  
  215.         } else if (mMinFlingVelocity <= velocityX  
  216.                 && velocityX <= mMaxFlingVelocity && velocityY < velocityX) {  
  217.             dismiss = true;  
  218.             dismissRight = mVelocityTracker.getXVelocity() > 0;  
  219.         }  
  220.   
  221.         if (dismiss) {  
  222.             ViewPropertyAnimator.animate(mDownView)  
  223.                     .translationX(dismissRight ? mViewWidth : -mViewWidth)//X軸方向的移動距離  
  224.                     .alpha(0)  
  225.                     .setDuration(mAnimationTime)  
  226.                     .setListener(new AnimatorListenerAdapter() {  
  227.                         @Override  
  228.                         public void onAnimationEnd(Animator animation) {  
  229.                             //Item滑出界面之後執行刪除  
  230.                             performDismiss(mDownView, mDownPosition);  
  231.                         }  
  232.                     });  
  233.         } else {  
  234.             //將item滑動至開始位置  
  235.             ViewPropertyAnimator.animate(mDownView)  
  236.             .translationX(0)  
  237.             .alpha(1)     
  238.             .setDuration(mAnimationTime).setListener(null);  
  239.         }  
  240.           
  241.         //移除速度檢測  
  242.         if(mVelocityTracker != null){  
  243.             mVelocityTracker.recycle();  
  244.             mVelocityTracker = null;  
  245.         }  
  246.           
  247.         mSwiping = false;  
  248.     }  
  249.       
  250.   
  251.       
  252.     /** 
  253.      * 在此方法中執行item刪除之後,其他的item向上或者向下滾動的動畫,並且將position回調到方法onDismiss()中 
  254.      * @param dismissView 
  255.      * @param dismissPosition 
  256.      */  
  257.     private void performDismiss(final View dismissView, final int dismissPosition) {  
  258.         final ViewGroup.LayoutParams lp = dismissView.getLayoutParams();//獲取item的佈局參數  
  259.         final int originalHeight = dismissView.getHeight();//item的高度  
  260.   
  261.         ValueAnimator animator = ValueAnimator.ofInt(originalHeight, 0).setDuration(mAnimationTime);  
  262.         animator.start();  
  263.   
  264.         animator.addListener(new AnimatorListenerAdapter() {  
  265.             @Override  
  266.             public void onAnimationEnd(Animator animation) {  
  267.                 if (onDismissCallback != null) {  
  268.                     onDismissCallback.onDismiss(dismissPosition);  
  269.                 }  
  270.   
  271.                 //這段代碼很重要,因爲我們並沒有將item從ListView中移除,而是將item的高度設置爲0  
  272.                 //所以我們在動畫執行完畢之後將item設置回來  
  273.                 ViewHelper.setAlpha(dismissView, 1f);  
  274.                 ViewHelper.setTranslationX(dismissView, 0);  
  275.                 ViewGroup.LayoutParams lp = dismissView.getLayoutParams();  
  276.                 lp.height = originalHeight;  
  277.                 dismissView.setLayoutParams(lp);  
  278.   
  279.             }  
  280.         });  
  281.   
  282.         animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {  
  283.             @Override  
  284.             public void onAnimationUpdate(ValueAnimator valueAnimator) {  
  285.                 //這段代碼的效果是ListView刪除某item之後,其他的item向上滑動的效果  
  286.                 lp.height = (Integer) valueAnimator.getAnimatedValue();  
  287.                 dismissView.setLayoutParams(lp);  
  288.             }  
  289.         });  
  290.   
  291.     }  
  292.   
  293.     /** 
  294.      * 刪除的回調接口 
  295.      *  
  296.      * @author xiaanming 
  297.      *  
  298.      */  
  299.     public interface OnDismissCallback {  
  300.         public void onDismiss(int dismissPosition);  
  301.     }  
  302.   
  303. }  
看過Android 使用Scroller實現絢麗的ListView左右滑動刪除Item效果你會發現,這個自定義的SwipeDismissListView只重寫了onTouchEvent()方法,其實我們重寫這一個方法就能實現我們需要的效果

1. 我們先看手指按下屏幕的處理方法handleActionDown();該方法裏面根據我們手指按下的點根據pointToPosition()方法來獲取我們點擊的position,然後利用getChildAt()來獲取我們按下的item的View對象,並且加入手指在屏幕滑動的速度檢查,這一步相對來說還是比較簡單


2. 接下來就是手指在屏幕上面滑動的處理方法handleActionMove(),這個方法就稍微的複雜些,我們需要根據手指在X軸的滑動距離和Y軸的滑動距離來判斷是ListView item的水平滑動還是ListView的上下滑動,當滿足Math.abs(deltaX) > mSlop && Math.abs(deltaY) < mSlop這個條件時候,我們用一個布爾值mSwiping來標記Item現在處於水平滑動的狀態,這時候我們需要處理Item跟隨手指的滑動而滑動的邏輯,我們使用ViewHelper來處理Item的滑動邏輯,這個類會根據機器的SDK版本來判斷使用Android系統的API還是NineOldandroids中自己實現的API使得View滑動的效果,NineOldandroids中主要使用Camera(可以實現各種複雜動畫效果的類),我們直接使用ViewHelper的setTranslationX()和setAlpha()就實現了item滑動和透明度漸變的效果,爲了使得我們在滑動item的時候,ListView不上下滾動,我們必須返回true來屏蔽ListView的上下滾動,這裏需要我們要非常熟悉Android的事件分發機制,這裏我就不說明了,大家不瞭解的去網上找找相關的文章看看
還有一個問題,就是當我們滑動ListView的item的時候,會伴隨着item的點擊事件,這不是我們想要的效果,所以當Item滑動的時候我們需要取消ListView Item的點擊事件


3. 在看手指擡起的時候的處理方法handleActionUp(),這裏面需要根據手指的滑動速度或者Item移動的距離來判斷Item是滑出屏幕還是滑動至起始位置,並且要判斷item向左還是向右滑出屏幕等等邏輯,具體的邏輯可以看代碼,相信大家都看得懂.

我這裏要說說ViewPropertyAnimator類,這個類能更好的實現一個View同時進行多個動畫的功能,當然我們也可以使用ObjectAnimator利用AnimatorSet來實現一個View上的多個同時進行的動畫效果,例如我們可以將

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. ViewPropertyAnimator.animate(mDownView)  
  2.         .translationX(dismissRight ? mViewWidth : -mViewWidth)//X軸方向的移動距離  
  3.         .alpha(0)  
  4.         .setDuration(mAnimationTime)  
  5.         .setListener(new AnimatorListenerAdapter() {  
  6.             @Override  
  7.             public void onAnimationEnd(Animator animation) {  
  8.                 //Item滑出界面之後執行刪除  
  9.                 performDismiss(mDownView, mDownPosition);  
  10.             }  
  11.         });  
替換成
[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. AnimatorSet set = new AnimatorSet();  
  2.             set.playTogether(ObjectAnimator.ofFloat(mDownView, "translationX", dismissRight ? mViewWidth : -mViewWidth),   
  3.                             ObjectAnimator.ofFloat(mDownView, "alpha"0));  
  4.             set.setDuration(mAnimationTime).start();  
  5.             set.addListener(new AnimatorListenerAdapter() {  
  6.                         @Override  
  7.                         public void onAnimationEnd(Animator animation) {  
  8.                             //Item滑出界面之後執行刪除  
  9.                             performDismiss(mDownView, mDownPosition);  
  10.                         }  
  11.                     });  
在效果上面是一樣的,但是ViewPropertyAnimator在性能上要比使用ObjectAnimator來實現多個同時進行的動畫要高的多,舉個例子,假如要對View使用移動和透明度的動畫,使用ViewPropertyAnimator的話,某個時間點上我們只需要調用一次invalidate()方法刷新界面就行了,而使用ObjectAnimator的話,移動的動畫需要調用invalidate(),透明度的動畫也需要調用invalidate()方法,在性能上使用AnimationSet比ViewPropertyAnimator要低,但是有的時候我們還是需要使用ObjectAnimator,比如,在某個時間內,我們需要將View先變大在變小在變大等複雜情況,這時候ObjectAnimator就派上用場了,例如
[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. ObjectAnimator.ofInt(mDownView, "scaleX"0 ,100 ,0100).setDuration(100).start()  

通過上面的幾步我們就實現了ListView的左右滑動刪除item的效果啦,但是還有一個效果,item刪除之後,ListView的其他item向上或者向下緩緩滑動的效果,實現這個也很容易,就是動態設置item的高度,item高度逐漸變小,這樣其他的item就會出現向上或者向下擠壓的效果啦!


4. 這裏我們使用的是ValueAnimator這個類,這個類並不是針對View作用的動畫,而是對某個值作用的動畫,他默認使用的Interpolator(插補器)是AccelerateDecelerateInterpolator(開始和結束的時候慢,中間快) , 舉個很簡單的例子,我們在10秒內使用ValueAnimator將某個值從0變化到100,如果使用LinearInterpolator(線性插補器,勻速變化)在第2秒的時候,這個值變成了20,而是用AccelerateDecelerateInterpolator,可能在第二秒的時候這個值爲15或者13,所以我們在ValueAnimator變化的時候設置值動畫變化的監聽器AnimatorUpdateListener就知道某個時間這個值變成了多少,從而對View的某個屬性進行設置(例如大小),所以ValueAnimator是間接的對View設置動畫的

瞭解了ValueAnimator的使用原理,我們就可以現實上面的動畫效果了,我們使用ValueAnimator將item的高度變成0,設置ValueAnimator變化的監聽,我們在回調函數onAnimationUpdate()中動態的設置item的高度, 然後添加AnimatorListener監聽動畫的狀態(例如動畫開始,結束,重複等)監聽,在動畫結束的回調函數onAnimationEnd()中刪除該item的數據,調用notifyDataSetChanged刷新ListView,看看下面這段代碼

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. ViewHelper.setAlpha(dismissView, 1f);  
  2.                 ViewHelper.setTranslationX(dismissView, 0);  
  3.                 ViewGroup.LayoutParams lp = dismissView.getLayoutParams();  
  4.                 lp.height = originalHeight;  
  5.                 dismissView.setLayoutParams(lp);  
我們使用動畫只是將item移動出了屏幕,並且將item的高度設置爲了0,並沒有將item的View從ListView中Remove掉,況且ListView也不能直接Remove掉Item的,只能將數據源刪除,在調用notifyDataSetChanged()刷新,所以我們需要將剛剛滑出屏幕高度設置爲0的Item恢復回來


自定義控件的代碼我們已經編寫完了,接下來我們就要使用它了,先看界面的佈局代碼

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    
  2.     xmlns:tools="http://schemas.android.com/tools"    
  3.     android:layout_width="match_parent"    
  4.     android:layout_height="match_parent">    
  5.     
  6.     <com.example.swipedismisslistview.SwipeDismissListView  
  7.         android:id="@+id/swipeDismissListView"    
  8.         android:layout_width="match_parent"    
  9.         android:layout_height="match_parent"   
  10.         android:listSelector="@android:color/transparent"  
  11.         android:cacheColorHint="@android:color/transparent">    
  12.     </com.example.swipedismisslistview.SwipeDismissListView>  
  13.     
  14. </RelativeLayout>    

很簡單,一個RelativeLayout包裹我們自定義的ListView控件,接下來就是主界面的代碼編寫,跟平常的ListView使用一樣,但是我們需要設置OnDismissCallback()監聽,在

onDismiss()中刪除該位置對於的數據,刷新ListView

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. package com.example.swipedismisslistview;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6. import android.app.Activity;  
  7. import android.os.Bundle;  
  8. import android.view.View;  
  9. import android.widget.AdapterView;  
  10. import android.widget.AdapterView.OnItemClickListener;  
  11. import android.widget.ArrayAdapter;  
  12. import android.widget.Toast;  
  13.   
  14. import com.example.swipedismisslistview.SwipeDismissListView.OnDismissCallback;  
  15.   
  16. public class SwipeActivity extends Activity {  
  17.     private SwipeDismissListView swipeDismissListView;  
  18.     private ArrayAdapter<String> adapter;  
  19.     private List<String> dataSourceList = new ArrayList<String>();  
  20.   
  21.     @Override  
  22.     protected void onCreate(Bundle savedInstanceState) {  
  23.         super.onCreate(savedInstanceState);  
  24.         setContentView(R.layout.activity_swipe);  
  25.         init();  
  26.     }  
  27.   
  28.     private void init() {  
  29.         swipeDismissListView = (SwipeDismissListView) findViewById(R.id.swipeDismissListView);  
  30.         for (int i = 0; i < 20; i++) {  
  31.             dataSourceList.add("滑動刪除" + i);  
  32.         }  
  33.   
  34.         adapter = new ArrayAdapter<String>(this,  
  35.                 android.R.layout.simple_list_item_1,  
  36.                 android.R.id.text1, dataSourceList);  
  37.           
  38.         swipeDismissListView.setAdapter(adapter);  
  39.           
  40.         swipeDismissListView.setOnDismissCallback(new OnDismissCallback() {  
  41.               
  42.             @Override  
  43.             public void onDismiss(int dismissPosition) {  
  44.                  adapter.remove(adapter.getItem(dismissPosition));   
  45.             }  
  46.         });  
  47.           
  48.           
  49.         swipeDismissListView.setOnItemClickListener(new OnItemClickListener() {  
  50.   
  51.             @Override  
  52.             public void onItemClick(AdapterView<?> parent, View view,  
  53.                     int position, long id) {  
  54.                 Toast.makeText(SwipeActivity.this, adapter.getItem(position), Toast.LENGTH_SHORT).show();  
  55.             }  
  56.         });  
  57.   
  58.     }  
  59.   
  60. }  
所有的代碼都已經編寫完畢了,接下來就是運行工程,看看具體的效果是不是我們想要的


好了,今天的講解到這裏結束了,有了NineOldAndroids我們可以在2.x的手機上面實現許多複雜的動畫效果,文章也介紹了關於開源庫NineOldAndroids使用的一些知識,文章有點長,希望讀者還是先將文章看下,然後自己看看能不能自己實現出來,有什麼不明白的地方請在下面留言,我會爲大家解答的!

項目源碼,點擊下載


ps: 下載源碼的時候運行出錯,是因爲我加入了NineOldAndroids的Jar包,然後又加入了NineOldAndroids工程庫,主要是我寫DEMO的時候爲了方便看源碼就導入了NineOldAndroids工程庫,大家刪除一個JAR包或者NineOldAndroids工程庫 就能解決了


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章