Android ListView動畫特效實現原理及源碼

來源:互聯網
上載者:User

Android ListView動畫特效實現原理及源碼

Android 動畫分三種,其中屬性動畫為我們最常用動畫,且能滿足項目中開發幾乎全部需求,google官方包支援3.0+,我們可以引用三方包nineoldandroids來失陪到低版本。本例子中就是用屬性動畫實現效果。

對普通的View做動畫,我們只要定義好要的動畫ObjectAnimator或AnimatorSet,然後設定屬性啟動及可。但是,對ListView做動畫應該如何、什麼時候、在什麼地方、對哪個View做動畫屬性呢?

github上有成熟的listview動畫包 https://github.com/nhaarman/ListViewAnimations.git , 基本可以滿足比較炫的效果,比如google+動態list載入,各種動態list顯示及刪除。問題是,如果不能滿足我們的需求,如何?自己想要的ListView動畫效果呢?研究github上項目實現原理髮現並不複雜,下面我們就參考開源項目實現自己的ListView動畫效果。

要想對ListView的Item做動畫,首先想到的是Adapter的getView()方法。在getView方面裡可以獲得每個Item view,然後定義好動畫效果,結合動畫需求對contentView做動畫。

如需要做一個刪除item時的動畫,可以在getView時把View和position傳給做的動畫或動畫集,這個比較簡單見代碼:

 

 

 

public static AnimatorSet buildListRemoveAnimator(final View view, final List list,            final MyAnimListAdapter adapter, final int index) {        AnimatorListener al = new AnimatorListener() {            @Override            public void onAnimationStart(Animator animation) {                // TODO Auto-generated method stub            }            @Override            public void onAnimationRepeat(Animator animation) {                // TODO Auto-generated method stub            }            @Override            public void onAnimationEnd(Animator animation) {                // TODO Auto-generated method stub                list.remove(index);                ViewHolder vh = (ViewHolder) view.getTag();                vh.needInflate = true;                adapter.notifyDataSetChanged();            }            @Override            public void onAnimationCancel(Animator animation) {                // TODO Auto-generated method stub            }        };        AnimatorSet animatorSet = new AnimatorSet();        Animator anim = ObjectAnimator.ofFloat(view, "rotationX", 0, 90);        Animator animb = ObjectAnimator.ofFloat(view, "alpha", 1, 0);        ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1);        final int height = view.getMeasuredHeight();        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                // TODO Auto-generated method stub                if (animation.getAnimatedFraction() >= 1) {                    view.setVisibility(View.GONE);                }                else {                    view.getLayoutParams().height = height                            - (int) (height * animation.getAnimatedFraction());                    view.requestLayout();                }            }        });        anim.setDuration(ANIMATION_DURATION);        animb.setDuration(ANIMATION_DURATION);        valueAnimator.setDuration(ANIMATION_DURATION + ANIMATION_DURATION + 100);        animatorSet.playTogether(anim, animb, valueAnimator);        animatorSet.addListener(al);        return animatorSet;    }


 

如何做一個listview動態現實每個Item的顯示效果。這個教刪除複雜,需要計算每個item動畫的開始時間,及判斷是否動畫現實,還有就是顯示動畫要按照什麼樣的規則或是順序, 計算動畫現實的時間等因素。並且不好最佳化list的效能,及顯示效果。下面的例子只是實現了基本動畫效果,效能最佳化欠缺。

 

 

public static AnimatorSet buildShowAnimatorList(ViewGroup parent, ListView list, View view, long mAnimationStartMillis,            int mLastAnimatedPosition, int mFirstAnimatedPosition) {        if (mAnimationStartMillis == -1) {            mAnimationStartMillis = System.currentTimeMillis();        }        ViewHelper.setAlpha(view, 0);        Animator alphaAnimator = ObjectAnimator.ofFloat(view, "alpha", 0, 1);        Animator rx = ObjectAnimator.ofFloat(view, "rotationX", -90, 0);        AnimatorSet set = new AnimatorSet();        set.playTogether(alphaAnimator, rx);        set.setStartDelay(calculateAnimationDelay(list, mLastAnimatedPosition, mFirstAnimatedPosition,mAnimationStartMillis));        set.setDuration(DEFAULTANIMATIONDELAYMILLIS);        set.start();        return set;    }    private static long calculateAnimationDelay(ListView list, int last, int first,long starmill) {        long delay;        int lastVisiblePosition = list.getLastVisiblePosition();        int firstVisiblePosition = list.getFirstVisiblePosition();        int numberOfItemsOnScreen = lastVisiblePosition - firstVisiblePosition;        int numberOfAnimatedItems = last - first;        if (numberOfItemsOnScreen + 1 < numberOfAnimatedItems) {            delay = DEFAULTANIMATIONDELAYMILLIS;        } else {            long delaySinceStart = (last - first + 1)                    * DEFAULTANIMATIONDELAYMILLIS;            delay = starmill + DEFAULTANIMATIONDELAYMILLIS + delaySinceStart                    - System.currentTimeMillis();        }        return Math.max(0, delay);    }


 

參照上面的方法可以實現自己想要的ListView Item動畫,並且可以去自訂想要的效果。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.