zoukankan      html  css  js  c++  java
  • 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动画,而且能够去自己定义想要的效果。

         本例源代码地址:

         https://github.com/CankingApp/ListAnimator 

          多多提建议。多多交流~

  • 相关阅读:
    [转]暴风电视开机卡死、闪屏怎么办
    暴风电视快速查询机器型号及平台
    暴风电视风行系统FUNOS插入U盘、移动硬盘不能写入文件。
    yum版本号前有:冒号 指的是依赖版本号,默认0不显示
    yum多个源repo安装指定版本docker
    [转]YUM的工作机制与配置
    yum!base仓库里的repo id(源标识)前有叹号
    Docker新旧版本号下载
    yum没有可用软件包 docker。错误:无须任何处理CentOS-Media.repo仓库
    【笔记整理】之 servlet
  • 原文地址:https://www.cnblogs.com/lytwajue/p/7347828.html
Copyright © 2011-2022 走看看