【发布时间】:2012-04-01 22:32:28
【问题描述】:
有没有办法在 Android 中打开可展开列表时添加动画? 我想要它,这样当用户点击可扩展列表时,它就会有一个动画/效果,就像我在打开一个滑动抽屉一样。
它移动缓慢,直到完全打开。
【问题讨论】:
标签: android expandablelistview android-sliding
有没有办法在 Android 中打开可展开列表时添加动画? 我想要它,这样当用户点击可扩展列表时,它就会有一个动画/效果,就像我在打开一个滑动抽屉一样。
它移动缓慢,直到完全打开。
【问题讨论】:
标签: android expandablelistview android-sliding
我花了很多时间搜索但没有运气。现有的解决方案不够流畅 - 如果您的布局比只有 2 个按钮更复杂,它就会变得滞后。
所以,我创建了自己的ListAdapter,将整个视图缓存到Bitmap,然后在缓存视图而不是视图本身上执行动画。它的工作速度快得多。
这里是:https://github.com/dmitry-zaitsev/ExpandableAdapter
好消息是您不需要重写一堆代码 - 只需将我的 ExpandableAdapter 包裹在您的适配器周围,并提供将充当切换按钮的视图的 ID 和视图的 ID保存第二层的内容:
new ExpandableAdapter(context, yourAdapter, R.id.switch, R.id.holder);
仅此而已。
【讨论】:
ExpandableListView 基本上没用(因为缺乏定制能力),所以这个解决方案打算用一堆ListView+ExpandableAdapter 替换ExpandableListView。
RecyclerView
我也尝试过完成这项工作。我找到了一种适用于 childViews 的解决方案。虽然它不会为组的实际扩展设置动画,但会在子单元格填充扩展留下的空间时为它们设置动画。
编辑:折叠有一个错误,它会使一些不应该隐藏的单元格被隐藏。这可能与listView中的View-recycling有关。当我有解决方案时,我会更新。
在 setOnGroupClickListener 中使用 layoutAnimation 制作动画
mResultList.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
@Override
public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
if(mResultList.isGroupExpanded(groupPosition)){
mProgAdap.prepareToCollapseGroup(groupPosition);
setupLayoutAnimationClose(groupPosition);
mResultList.requestLayout();
}else{
boolean autoScrollToExpandedGroup = false;
mResultList.expandGroup(groupPosition,autoScrollToExpandedGroup);
setupLayoutAnimation();
//*/
}
//telling the listView we have handled the group click, and don't want the default actions.
return true;
}
private void setupLayoutAnimation() {
AnimationSet set = new AnimationSet(true);
Animation animation = new AlphaAnimation(0.0f, 1.0f);
animation.setDuration(50);
set.addAnimation(animation);
animation = new ScaleAnimation(1.0f, 1.0f, 0.0f, 1.0f, 0.5f, 1.0f);
animation.setDuration(50);
set.addAnimation(animation);
LayoutAnimationController controller = new LayoutAnimationController(set, 0.75f);
mResultList.setLayoutAnimationListener(null);
mResultList.setLayoutAnimation(controller);
}
private void setupLayoutAnimationClose(final int groupPosition) {
AnimationSet set = new AnimationSet(true);
Animation animation = new AlphaAnimation(1.0f, 0.0f);
animation.setDuration(50);
animation.setFillAfter(true);
animation.setFillEnabled(true);
set.addAnimation(animation);
animation = new ScaleAnimation(1.0f, 1.0f, 1.0f, 0.0f, 0.5f, 0.0f);
animation.setDuration(50);
animation.setFillAfter(true);
animation.setFillEnabled(true);
set.addAnimation(animation);
set.setFillAfter(true);
set.setFillEnabled(true);
LayoutAnimationController controller = new LayoutAnimationController(set, 0.75f);
controller.setOrder(LayoutAnimationController.ORDER_REVERSE);
mResultList.setLayoutAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
mResultList.collapseGroup(groupPosition);
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
mResultList.setLayoutAnimation(controller);
}
});
我们需要进行更多调整以使动画仅适用于展开/折叠组的实际子项。因为我们无法在 LayoutAnimationController 中重载正确的部分,所以我们需要创建一个特殊的 ViewGroup 类。这与"Can LayoutAnimationController animate only specified Views" 中的技术相同。
在 ExpandableListViewAdapter 中,我们现在需要一些状态处理来允许或忽略列表中项目的动画。
@Override
public void onGroupExpanded(int groupPos){
super.onGroupExpanded(groupPos);
int childCount = getChildrenCount(groupPos);
Log.d("EXPLIST","setting children to be expanded:" + childCount);
for(int j=0; j < getGroupCount(); j++){
for(int k=0; k < getChildrenCount(j); k++){
GoalServiceCell cell = (GoalServiceCell)getChild(j,k);
cell.expandAnimState = GoalServiceCell.ExpandAnimState.SHOULD_NOT_ANIMATE;
}
}
for(int i=0; i < childCount; i++){
GoalServiceCell cell = (GoalServiceCell)getChild(groupPos,i);
cell.expandAnimState = GoalServiceCell.ExpandAnimState.SHOULD_START_EXPAND;
}
}
public void prepareToCollapseGroup(int groupPos){
int childCount = getChildrenCount(groupPos);
for(int j=0; j < getGroupCount(); j++){
for(int k=0; k < getChildrenCount(j); k++){
GoalServiceCell cell = (GoalServiceCell)getChild(j,k);
cell.expandAnimState = GoalServiceCell.ExpandAnimState.SHOULD_NOT_ANIMATE;
}
}
for(int i=0; i < childCount; i++){
GoalServiceCell cell = (GoalServiceCell)getChild(groupPos,i);
cell.expandAnimState = GoalServiceCell.ExpandAnimState.SHOULD_START_COLLAPSIN;
}
}
@Override
public void onGroupCollapsed(int groupPos){
super.onGroupCollapsed(groupPos);
int childCount = getChildrenCount(groupPos);
for(int i=0; i < childCount; i++){
GoalServiceCell cell = (GoalServiceCell)getChild(groupPos,i);
cell.expandAnimState = GoalServiceCell.ExpandAnimState.SHOULD_NOT_ANIMATE;
}
}
在孩子的 ViewHolder 中。
void expandOrCollapse(GoalServiceCell cell,int position){
AnimationAverseRelativeLayout hack = (AnimationAverseRelativeLayout)master;
boolean shouldAnim = cell.expandAnimState == GoalServiceCell.ExpandAnimState.SHOULD_START_EXPAND ||
cell.expandAnimState == GoalServiceCell.ExpandAnimState.SHOULD_START_COLLAPSIN;
hack.setIfShouldAnimate(shouldAnim);
}
GroupView 也包含在 AnimationAverseRelativeLayout 中。由于我已将“shouldAnimate”设置为默认为 false,因此我不需要触摸它们。
【讨论】:
if(mResultList.isGroupExpanded(groupPosition)){ mProgAdap.prepareToCollapseGroup(groupPosition); setupLayoutAnimationClose(groupPosition); mResultList.requestLayout(); } 更改为if(mResultList.isGroupExpanded(groupPosition)){ mResultList.collapseGroup(groupPosition); } 以正确禁用折叠动画?
我遇到了同样的问题。我一劳永逸地修复了它。我把它开源到 github。 https://github.com/tjerkw/Android-SlideExpandableListView
基本上,您将这个项目依赖项包含在您的 Android 项目中。然后将您的ListAdapter 包装成SlideExpandableListAdapter。然后包装器会将带有动画的幻灯片功能添加到您的ListView。
希望对你有所帮助,我已经在两个项目中使用它了。
【讨论】:
anim height -48 或 0 ;有什么想法吗?
所以我所做的是使用常规的ListView,然后在 onListItemClick 中执行动画。
动画与我在此链接中所做的类似:Android animate drop down/up view proper
但仅适用于行视图的一部分。行视图在xml中的实现方式如下:
<somelayout>
<normal>
</normal>
<expanded>
</expanded>
</somelayout>
正常使用没有展开。当扩展被激活时,扩展被设置为可见而不是消失。您需要控制在关闭时将其设置为再次消失(请记住,这是在您的可回收的转换视图中设置的)。
如果需要,我可以进一步澄清,只是需要输入大量代码。
【讨论】:
这就是我在这种情况下所做的。
ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(list1, PropertyValuesHolder.ofInt("底部", currentlistHeight,currentlistHeight*2 ));
这样做的结果是 listView 的高度会加倍,并且会被动画化。 如果设置当前列表高度ZERO。这就像一个抽屉。
【讨论】: