SlideExpandableListView--有滑动效果ExpandableListView

【SlideExpandableListView--有滑动效果ExpandableListView】Github项目 git@github.com:tjerkw/Android-SlideExpandableListView.git
最近项目中有一个列表展示的效果,ExpandableListView的样式,但是要求列表展开关闭的时候有滑动效果,貌似ExpandableListView实现起来比较麻烦,开始时参考了git@github.com:idunnololz/AnimatedExpandableListView.git这个项目,但是效果并不理想,于是使用了本文开篇的项目。下面对这个动画源码分析一下,加深理解。
1. 项目结构 类图如下:

SlideExpandableListView--有滑动效果ExpandableListView
文章图片
image 结构很简单,一个自定义的ListView和一个自定义的ListAdapterview部分绑定按钮的事件,adapter部分生成view,主要功能在AbstractSlideExpandableListAdapter类中实现。
sample截图:
SlideExpandableListView--有滑动效果ExpandableListView
文章图片
image 点击More按钮的时候,内容部分会进行平移的折叠或者显示。
2. 动画实现部分 动画部分在ExpandCollapseAnimation中实现
protected void applyTransformation(float interpolatedTime, Transformation t) { super.applyTransformation(interpolatedTime, t); if (interpolatedTime < 1.0f) { if(mType == EXPAND) { mLayoutParams.bottomMargin =-mEndHeight + (int) (mEndHeight * interpolatedTime); } else { mLayoutParams.bottomMargin = - (int) (mEndHeight * interpolatedTime); } Log.d("ExpandCollapseAnimation", "anim height " + mLayoutParams.bottomMargin); mAnimatedView.requestLayout(); } else { if(mType == EXPAND) { mLayoutParams.bottomMargin = 0; mAnimatedView.requestLayout(); } else { mLayoutParams.bottomMargin = -mEndHeight; mAnimatedView.setVisibility(View.GONE); mAnimatedView.requestLayout(); } } }

mEndHeight在构造时初始化,是滑动动画控件的高度。本质是通过不断变化目标view的bottomMargin属性来实现动画效果,若是collapse,动画完成后(interpolatedTime变为1时)将控件隐藏。
3. 动画的触发 动画通过点击More按钮触发,按钮的事件绑定在AbstractSlideExpandableListAdapter文件中,在getView时进行绑定。
关键代码
target.setAnimation(null); int type = target.getVisibility() == View.VISIBLE ? ExpandCollapseAnimation.COLLAPSE : ExpandCollapseAnimation.EXPAND; // remember the state if (type == ExpandCollapseAnimation.EXPAND) { openItems.set(position, true); } else { openItems.set(position, false); } // check if we need to collapse a different view if (type == ExpandCollapseAnimation.EXPAND) { if (lastOpenPosition != -1 && lastOpenPosition != position) { if (lastOpen != null) { animateView(lastOpen, ExpandCollapseAnimation.COLLAPSE); notifiyExpandCollapseListener(ExpandCollapseAnimation.COLLAPSE, lastOpen, lastOpenPosition); } openItems.set(lastOpenPosition, false); } lastOpen = target; lastOpenPosition = position; } else if (lastOpenPosition == position) { lastOpenPosition = -1; } animateView(target, type); notifiyExpandCollapseListener(type, target, position);

  • View lastOpen用来记录上次打开的view对象。
  • int lastOpenPosition记录上次打开的view的position
  • BitSet openItems用来记录当前打开的view的position
  • animateView(View targt, int type)target上根据type执行动画,打开或关闭。
打开时首先检查是否有其他的项目已经打开,如果有则先关闭已经打开的。然后在当前view上执行动画。

    推荐阅读