package com.huyingzi.animatedexpandablelistviewdemo.view;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.util.AttributeSet;
import android.util.SparseArray;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.Transformation;
import android.widget.AbsListView;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import java.util.ArrayList;
import java.util.List;
/**
* This class defines an ExpandableListView which supports animations for collapsing and expanding groups.
* 这个类扩展了ExpandableListView 增加了折叠动画
*/
public class AnimatedExpandableListView extends ExpandableListView {
/*
* A detailed explanation for how this class works:
*
* Animating the ExpandableListView was no easy task.
* The way that this class does it is by exploiting how an ExpandableListView works.
* Normally when {@link ExpandableListView#collapseGroup(int)} or
* {@link ExpandableListView#expandGroup(int)} is called, the view toggles
* the flag for a group and calls notifyDataSetChanged to cause the ListView
* to refresh all of it's view. This time however, depending on whether a
* group is expanded or collapsed, certain childViews will either be ignored
* or added to the list.
*
* Knowing this, we can come up with a way to animate our views. For
* instance for group expansion, we tell the adapter to animate the
* children of a certain group. We then expand the group which causes the
* ExpandableListView to refresh all views on screen. The way that
* ExpandableListView does this is by calling getView() in the adapter.
* However since the adapter knows that we are animating a certain group,
* instead of returning the real views for the children of the group being
* animated, it will return a fake dummy view. This dummy view will then
* draw the real child views within it's dispatchDraw function. The reason
* we do this is so that we can animate all of it's children by simply
* animating the dummy view. After we complete the animation, we tell the
* adapter to stop animating the group and call notifyDataSetChanged. Now
* the ExpandableListView is forced to refresh it's views again, except this
* time, it will get the real views for the expanded group.
*
* So, to list it all out, when {@link #expandGroupWithAnimation(int)} is
* called the following happens:
*
* 1. The ExpandableListView tells the adapter to animate a certain group.
* 2. The ExpandableListView calls expandGroup.
* 3. ExpandGroup calls notifyDataSetChanged.
* 4. As an result, getChildView is called for expanding group.
* 5. Since the adapter is in "animating mode", it will return a dummy view.
* 6. This dummy view draws the actual children of the expanding group.
* 7. This dummy view's height is animated from 0 to it's expanded height.
* 8. Once the animation completes, the adapter is notified to stop
* animating the group and notifyDataSetChanged is called again.
* 9. This forces the ExpandableListView to refresh all of it's views again.
* 10.This time when getChildView is called, it will return the actual
* child views.
*
* For animating the collapse of a group is a bit more difficult since we
* can't call collapseGroup from the start as it would just ignore the
* child items, giving up no chance to do any sort of animation. Instead
* what we have to do is play the animation first and call collapseGroup
* after the animation is done.
*
* So, to list it all out, when {@link #collapseGroupWithAnimation(int)} is
* called the following happens:
*
* 1. The ExpandableListView tells the adapter to animate a certain group.
* 2. The ExpandableListView calls notifyDataSetChanged.
* 3. As an result, getChildView is called for expanding group.
* 4. Since the adapter is in "animating mode", it will return a dummy view.
* 5. This dummy view draws the actual children of the expanding group.
* 6. This dummy view's height is animated from it's current height to 0.
* 7. Once the animation completes, the adapter is notified to stop
* animating the group and notifyDataSetChanged is called again.
* 8. collapseGroup is finally called.
* 9. This forces the ExpandableListView to refresh all of it's views again.
* 10.This time when the ListView will not get any of the child views for
* the collapsed group.
*/
@SuppressWarnings("unused")
private static final String TAG = AnimatedExpandableListAdapter.class.getSimpleName();
/**
* The duration of the expand/collapse animations
*/
private static final int ANIMATION_DURATION = 300;
private AnimatedExpandableListAdapter adapter;
public AnimatedExpandableListView(Context context) {
super(context);
}
public AnimatedExpandableListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public AnimatedExpandableListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
/**
* @see ExpandableListView#setAdapter(ExpandableListAdapter)
*/
public void setAdapter(ExpandableListAdapter adapter) {
super.setAdapter(adapter);
// Make sure that the adapter extends AnimatedExpandableListAdapter
//
if(adapter instanceof AnimatedExpandableListAdapter) {
this.adapter = (AnimatedExpandableListAdapter) adapter;
this.adapter.setParent(this);
} else {
throw new ClassCastException(adapter.toString() + " must implement AnimatedExpandableListAdapter");
}
}
/**
* Expands the given group with an animation.
* @param groupPos The position of the group to expand
* @return Returns true if the group was expanded. False if the group was
* already expanded.
*/
@SuppressLint("NewApi")
public boolean expandGroupWithAnimation(int groupPos) {
boolean lastGroup = groupPos == adapter.getGroupCount() - 1;
if (lastGroup && Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
return expandGroup(groupPos, true);
}
int groupFlatPos = getFlatListPosition(getPackedPositionForGroup(groupPos));
if (groupFlatPos != -1) {
int childIndex = groupFlatPos - getFirstVisiblePosition();
if (childIndex < getChildCount()) {
// Get the view for the group is it is on screen...
View v = getChildAt(childIndex);
if (v.getBottom() >= getBottom()) {
// If the user is not going to be able to see the animation
// we just expand the group without an animation.
// This resolves the case where getChildView will not be
// called if the children of the group is not on screen
// We need to notify the adapter that the group was expanded
// without it's knowledge
adapter.notifyGroupExpanded(groupPos);
return expandGroup(groupPos);
}
}
}
// Let the adapter know that we are starting the animation...
adapter.startExpandAnimation(groupPos, 0);
// Finally call expandGroup (note that expandGroup will call
// notifyDataSetChanged so we don't need to)
return expandGroup(groupPos);
}
/**
* Collapses the given group wit
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
使用ExpandableListView打造的可折叠的多条目布局的效果,每个Item里面的布局都可以自己定义,并且扩展了ExpandableListView的功能添加了折叠动画的效果。 项目使用AS2.3和gradle_3.3构建 Github下载地址: https://github.com/343906936/AnimatedExpandableListViewDemo
资源推荐
资源详情
资源评论
收起资源包目录
AnimatedExpandableListViewDemo.zip (39个子文件)
AnimatedExpandableListViewDemo
gradlew 5KB
settings.gradle 16B
gradle
wrapper
gradle-wrapper.properties 236B
gradle-wrapper.jar 52KB
gradlew.bat 2KB
gradle.properties 747B
.gitignore 127B
app
src
androidTest
java
com
huyingzi
animatedexpandablelistviewdemo
ExampleInstrumentedTest.java 816B
test
java
com
huyingzi
animatedexpandablelistviewdemo
ExampleUnitTest.java 437B
main
AndroidManifest.xml 766B
res
mipmap-hdpi
ic_launcher.png 3KB
ic_launcher_round.png 4KB
mipmap-xxxhdpi
ic_launcher.png 10KB
ic_launcher_round.png 14KB
mipmap-xhdpi
ic_launcher.png 5KB
ic_launcher_round.png 6KB
mipmap-mdpi
ic_launcher.png 2KB
ic_launcher_round.png 2KB
drawable
bg_item_child.xml 351B
bg_item_name.xml 345B
layout
item_group.xml 807B
item_child_four.xml 1KB
item_child_three.xml 785B
item_child_two.xml 720B
item_child_five.xml 2KB
item_child_one.xml 748B
activity_main.xml 634B
values
colors.xml 214B
strings.xml 334B
styles.xml 392B
mipmap-xxhdpi
ic_launcher.png 8KB
ic_launcher_round.png 10KB
java
com
huyingzi
animatedexpandablelistviewdemo
view
AnimatedExpandableListView.java 25KB
main
DemoAdapter.java 6KB
MainActivity.java 2KB
libs
.gitignore 8B
build.gradle 990B
proguard-rules.pro 941B
build.gradle 521B
共 39 条
- 1
资源评论
Base_IT南
- 粉丝: 0
- 资源: 1
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功