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动画,而且能够去自己定义想要的效果。
本例源代码地址:
https://github.com/CankingApp/ListAnimator
多多提建议。多多交流~