[v1]
[v2]
的垂直linearLayout,默认情况下v1的可见性= GONE。我想显示带有扩展动画的v1,并同时按下v2。
我尝试了以下操作:
Animation a = new Animation()
{
int initialHeight;
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
final int newHeight = (int)(initialHeight * interpolatedTime);
v.getLayoutParams().height = newHeight;
v.requestLayout();
}
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
initialHeight = height;
}
@Override
public boolean willChangeBounds() {
return true;
}
};
但是有了这个解决方案,动画开始时我眨了眨眼。我认为这是由v1在应用动画之前显示完整尺寸引起的。
使用javascript,这是jQuery的一行!使用android进行此操作的任何简单方法?
#1 楼
我看到这个问题开始流行,所以我发布了实际的解决方案。主要优点是您不必知道扩展的高度即可应用动画,并且一旦视图被扩展,如果内容更改,视图就会适应高度。public static void expand(final View v) {
int matchParentMeasureSpec = View.MeasureSpec.makeMeasureSpec(((View) v.getParent()).getWidth(), View.MeasureSpec.EXACTLY);
int wrapContentMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
v.measure(matchParentMeasureSpec, wrapContentMeasureSpec);
final int targetHeight = v.getMeasuredHeight();
// Older versions of android (pre API 21) cancel animations for views with a height of 0.
v.getLayoutParams().height = 1;
v.setVisibility(View.VISIBLE);
Animation a = new Animation()
{
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
v.getLayoutParams().height = interpolatedTime == 1
? LayoutParams.WRAP_CONTENT
: (int)(targetHeight * interpolatedTime);
v.requestLayout();
}
@Override
public boolean willChangeBounds() {
return true;
}
};
// Expansion speed of 1dp/ms
a.setDuration((int)(targetHeight / v.getContext().getResources().getDisplayMetrics().density));
v.startAnimation(a);
}
public static void collapse(final View v) {
final int initialHeight = v.getMeasuredHeight();
Animation a = new Animation()
{
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
if(interpolatedTime == 1){
v.setVisibility(View.GONE);
}else{
v.getLayoutParams().height = initialHeight - (int)(initialHeight * interpolatedTime);
v.requestLayout();
}
}
@Override
public boolean willChangeBounds() {
return true;
}
};
// Collapse speed of 1dp/ms
a.setDuration((int)(initialHeight / v.getContext().getResources().getDisplayMetrics().density));
v.startAnimation(a);
}
正如@Jefferson在评论中所提到的,您可以通过更改持续时间(以及速度)来获得更平滑的动画。动画。目前,它的设置速度为1dp / ms
评论
v.measure(MeasureSpec.makeMeasureSpec(LayoutParams.MATCH_PARENT,MeasureSpec.EXACTLY),MeasureSpec.makeMeasureSpec(LayoutParams.WRAP_CONTENT,MeasureSpec.EXACTLY));在某些情况下(我-ListView),这种不匹配会导致错误的targtetHeight值
–Johnny Doe
2013年6月27日18:43
@Tom Esterez这确实有效,但不是很顺利。还有其他工作可以使它顺利进行吗?
–acntwww
13年7月19日在2:12
@acntwww您可以获得平稳的动画,将持续时间乘以某个因子,例如4。a.setDuration(((int)(initialHeight / v.getContext()。getResources()。getDisplayMetrics()。density))* 4)
– Jefferson Henrique C. Soares
2013年9月25日在21:08
@Alioo,导入android.view.animation.Transformation;
–乔米亚
2014年8月25日上午10:42
很棒!我想扩展固定的dp元素时遇到测量高度的问题,因此我将测量值更改为v.measure(View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED),View.MeasureSpec.makeMeasureSpec(0,View)。 MeasureSpec.UNSPECIFIED));和v.getLayoutParams()。height = interpolatedTime == 1吗? targetHeight:(int)(targetHeight * interpolatedTime);那对我有用!
–vkislicins
15年8月22日在11:27
#2 楼
我今天偶然发现了相同的问题,我想这个问题的真正解决方案是<LinearLayout android:id="@+id/container"
android:animateLayoutChanges="true"
...
/>
您将必须为所有涉及到的最顶层布局设置此属性。在轮班。如果现在将一种布局的可见性设置为GONE,则另一种布局将占用该空间,因为消失的一种布局正在释放它。将有一个默认的动画,某种程度上是“淡出”的,但是我认为您可以更改此动画-但到目前为止,我还没有测试过最后一个动画。
评论
+1,现在我正在搜索Speed:animateLayoutChanges的持续时间
–图莎·潘迪(Tushar Pandey)
2014年4月29日在7:14
动画版式更改:developer.android.com/training/animation/layout.html
–ccpizza
2014年5月18日13:10
按下返回按钮后不起作用。有什么建议?
–哈桑·塔雷克(Hassan Tareq)
17年4月10日在4:58
这对于展开动画非常有效,但对于折叠动画,发生在父布局缩小后进行。
– shine_joseph
'18 Sep 3'在6:43
@shine_joseph是的,我在recyclerview中使用它,当折叠看起来真的很奇怪:/
– AmirG
18-09-28在13:58
#3 楼
我试图做我认为非常相似的动画,并找到了一种优雅的解决方案。此代码假定您始终从0-> h或h-> 0(h为最大高度)出发。构造函数的三个参数是view =要动画化的视图(在我的情况下是webview),targetHeight =视图的最大高度,down =指示方向的布尔值(true =展开,false =折叠)。 br />public class DropDownAnim extends Animation {
private final int targetHeight;
private final View view;
private final boolean down;
public DropDownAnim(View view, int targetHeight, boolean down) {
this.view = view;
this.targetHeight = targetHeight;
this.down = down;
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
int newHeight;
if (down) {
newHeight = (int) (targetHeight * interpolatedTime);
} else {
newHeight = (int) (targetHeight * (1 - interpolatedTime));
}
view.getLayoutParams().height = newHeight;
view.requestLayout();
}
@Override
public void initialize(int width, int height, int parentWidth,
int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
}
@Override
public boolean willChangeBounds() {
return true;
}
}
评论
代码中有一个错字:“ initalize”方法名称应为“ initialize”,否则将不会被调用。 ;)我建议以后使用@Override,这样编译器会捕获这种错字。
–Lorne Laliberte
2011-09-28 3:57
我正在执行以下操作:“ DropDownAnim anim = new DropDownAnim(grid_titulos_atual,GRID_HEIGHT,true); anim.setDuration(500); anim.start();”但它不起作用。我在applyTransformation上放置了一些断点,但从未达到
– Paulo Cesar
2011-12-5 14:03
操作,让它正常工作,它是view.startAnimation(a)...性能不是很好,但是它可以工作:)
– Paulo Cesar
2011-12-5 16:16
@IamStalker在这种情况下,您可能应该使用两个变量进行初始化,开始高度和结束高度。然后更改为:if(down){newHeight =(int)((((endingHeight-startingHeight)* interpolatedTime)+ startingHeight); } else {newHeight =(int)((((endingHeight-startingHeight)*(1-interpolatedTime))+ startingHeight); }
–塞斯·尼尔森(Seth Nelson)
2012年6月4日4:44
@Seth我认为newHeight可以简单地是(int)((((targetHeight -startingHeight)* interpolatedTime)+ startingHeight)+起始方向,只要在initialize()中设置了startHeight即可。
– Giorgos Kylafas
2012年9月6日上午8:18
#4 楼
我使用了@LenaYan的解决方案,该解决方案对我来说无法正常运行(因为它在折叠和/或展开之前将View转换为0高度视图)并进行了一些更改。现在,通过采用View的先前高度并以此尺寸开始扩展,它可以很好地工作。折叠是相同的。
您只需复制并粘贴以下代码即可:
public static void expand(final View v, int duration, int targetHeight) {
int prevHeight = v.getHeight();
v.setVisibility(View.VISIBLE);
ValueAnimator valueAnimator = ValueAnimator.ofInt(prevHeight, targetHeight);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
v.getLayoutParams().height = (int) animation.getAnimatedValue();
v.requestLayout();
}
});
valueAnimator.setInterpolator(new DecelerateInterpolator());
valueAnimator.setDuration(duration);
valueAnimator.start();
}
public static void collapse(final View v, int duration, int targetHeight) {
int prevHeight = v.getHeight();
ValueAnimator valueAnimator = ValueAnimator.ofInt(prevHeight, targetHeight);
valueAnimator.setInterpolator(new DecelerateInterpolator());
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
v.getLayoutParams().height = (int) animation.getAnimatedValue();
v.requestLayout();
}
});
valueAnimator.setInterpolator(new DecelerateInterpolator());
valueAnimator.setDuration(duration);
valueAnimator.start();
}
用法:
//Expanding the View
expand(yourView, 2000, 200);
// Collapsing the View
collapse(yourView, 2000, 100);
很简单!
感谢LenaYan提供初始代码!
评论
虽然有效,但取决于开发人员设置(动画持续时间)。如果禁用此选项,则不会显示动画。
– CoolMind
16年7月29日在20:48
是的,但这可能是问题,也可能不是问题。取决于您的应用程序。例如,您可以通过简单的更改轻松地使动画的持续时间与扩展/收缩的大小成比例。可设置的动画持续时间为您提供了更多自由。
–杰拉尔多·内图(Geraldo Neto)
16-10-9在1:15
展开动画不起作用。它看起来像崩溃动画。
–阿哈马杜拉(Ahamadullah Saikat)
19/12/28在5:15
#5 楼
一种替代方法是使用具有以下缩放因子的缩放动画进行扩展:ScaleAnimation anim = new ScaleAnimation(1, 1, 0, 1);
和折叠:
ScaleAnimation anim = new ScaleAnimation(1, 1, 1, 0);
评论
如何开始动画。View.startAnimation(anim);似乎不起作用
–马亨德兰
2012年6月28日在8:57
这就是我开始动画的方式。其他动画对您有用吗?
– Christopher
2012年6月28日在9:20
采用这种方法,就像一个魅力,不需要实施已经实施的方法。
–erbsman
2012年10月29日14:32
在动画过程中,这不会将视图下移,并且看起来好像是从0-> h拉伸动画视图一样。
–user901309
2012年12月4日14:47
顺便说一句,视图动画非常适合缩放:oView.animate()。scaleY(0)可以垂直折叠; oView.animate()。scaleY(1)打开(注意,它仅适用于sdk 12及更高版本)。
– Kirk B.
13年1月15日在8:00
#6 楼
@Tom Esterez的答案,但已更新为根据Android getMeasuredHeight正确使用view.measure()返回错误的值! // http://easings.net/
Interpolator easeInOutQuart = PathInterpolatorCompat.create(0.77f, 0f, 0.175f, 1f);
public static Animation expand(final View view) {
int matchParentMeasureSpec = View.MeasureSpec.makeMeasureSpec(((View) view.getParent()).getWidth(), View.MeasureSpec.EXACTLY);
int wrapContentMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
view.measure(matchParentMeasureSpec, wrapContentMeasureSpec);
final int targetHeight = view.getMeasuredHeight();
// Older versions of android (pre API 21) cancel animations for views with a height of 0 so use 1 instead.
view.getLayoutParams().height = 1;
view.setVisibility(View.VISIBLE);
Animation animation = new Animation() {
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
view.getLayoutParams().height = interpolatedTime == 1
? ViewGroup.LayoutParams.WRAP_CONTENT
: (int) (targetHeight * interpolatedTime);
view.requestLayout();
}
@Override
public boolean willChangeBounds() {
return true;
}
};
animation.setInterpolator(easeInOutQuart);
animation.setDuration(computeDurationFromHeight(view));
view.startAnimation(animation);
return animation;
}
public static Animation collapse(final View view) {
final int initialHeight = view.getMeasuredHeight();
Animation a = new Animation() {
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
if (interpolatedTime == 1) {
view.setVisibility(View.GONE);
} else {
view.getLayoutParams().height = initialHeight - (int) (initialHeight * interpolatedTime);
view.requestLayout();
}
}
@Override
public boolean willChangeBounds() {
return true;
}
};
a.setInterpolator(easeInOutQuart);
int durationMillis = computeDurationFromHeight(view);
a.setDuration(durationMillis);
view.startAnimation(a);
return a;
}
private static int computeDurationFromHeight(View view) {
// 1dp/ms * multiplier
return (int) (view.getMeasuredHeight() / view.getContext().getResources().getDisplayMetrics().density);
}
评论
什么是addHeight和DURATION_MULTIPLIER?
– MidasLefko
15年10月22日在13:05
忘了这些,addHeight是在扩展中需要额外高度的情况下(可能不需要),而DURATION_MODIFIER只是速度修改器,以用于加速/减速动画。
– Erik B
15-10-22在18:24
很棒!使用TextView的最后一行只有一个单词时,会出现一小段延迟。您能解释一下PathInterpolator的功能吗?
– yennsarah
2015年11月9日在9:17
easeInOutQuart首先使动画变慢,然后再变快,最后使变慢,从而获得非常自然的感觉。他们在这里进一步谈论了easings.net
– Erik B
15年11月9日,19:54
我尝试了您的方法,但是只要动画结束,我的视图就不再可见。
–阿曼·维尔玛(Aman Verma)
16 Dec 21'在15:57
#7 楼
好的,我只是找到了一个非常丑陋的解决方案:public static Animation expand(final View v, Runnable onEnd) {
try {
Method m = v.getClass().getDeclaredMethod("onMeasure", int.class, int.class);
m.setAccessible(true);
m.invoke(
v,
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(((View)v.getParent()).getMeasuredHeight(), MeasureSpec.AT_MOST)
);
} catch (Exception e){
Log.e("test", "", e);
}
final int initialHeight = v.getMeasuredHeight();
Log.d("test", "initialHeight="+initialHeight);
v.getLayoutParams().height = 0;
v.setVisibility(View.VISIBLE);
Animation a = new Animation()
{
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
final int newHeight = (int)(initialHeight * interpolatedTime);
v.getLayoutParams().height = newHeight;
v.requestLayout();
}
@Override
public boolean willChangeBounds() {
return true;
}
};
a.setDuration(5000);
v.startAnimation(a);
return a;
}
随意提出更好的解决方案!
评论
+1,即使它被命名为丑陋,它也适用于我们尚不知道其大小的视图(例如,如果我们要向父级添加一个新创建的视图(其大小为FILL_PARENT),并希望为其设置动画这个过程,包括为父级大小的动画制作动画)。
–维特·胡登科(Vit Khudenko)
2012年8月26日13:32
顺便说一句,在View.onMeause(widthMeasureSpec,heightMeasureSpec)调用中似乎有一个小错误,因此应该交换宽度和高度规格。
–维特·胡登科(Vit Khudenko)
2012年8月27日13:24
#8 楼
public static void expand(final View v, int duration, int targetHeight) {
v.measure(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
v.getLayoutParams().height = 0;
v.setVisibility(View.VISIBLE);
ValueAnimator valueAnimator = ValueAnimator.ofInt(0, targetHeight);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
v.getLayoutParams().height = (int) animation.getAnimatedValue();
v.requestLayout();
}
});
valueAnimator.setInterpolator(new DecelerateInterpolator());
valueAnimator.setDuration(duration);
valueAnimator.start();
}
public static void collapse(final View v, int duration, int targetHeight) {
ValueAnimator valueAnimator = ValueAnimator.ofInt(0, targetHeight);
valueAnimator.setInterpolator(new DecelerateInterpolator());
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
v.getLayoutParams().height = (int) animation.getAnimatedValue();
v.requestLayout();
}
});
valueAnimator.setInterpolator(new DecelerateInterpolator());
valueAnimator.setDuration(duration);
valueAnimator.start();
}
评论
我有这个问题...可折叠视图内的内容在扩展时消失了。我有“回收者视图”,该视图在扩展此视图时消失。 @LenaYan
–阿克斯海·马哈詹(Akshay Mahajan)
18年6月10日在11:50
#9 楼
如果您不想一直扩展或折叠-这是一个简单的HeightAnimation-import android.view.View;
import android.view.animation.Animation;
import android.view.animation.Transformation;
public class HeightAnimation extends Animation {
protected final int originalHeight;
protected final View view;
protected float perValue;
public HeightAnimation(View view, int fromHeight, int toHeight) {
this.view = view;
this.originalHeight = fromHeight;
this.perValue = (toHeight - fromHeight);
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
view.getLayoutParams().height = (int) (originalHeight + perValue * interpolatedTime);
view.requestLayout();
}
@Override
public boolean willChangeBounds() {
return true;
}
}
用法:
HeightAnimation heightAnim = new HeightAnimation(view, view.getHeight(), viewPager.getHeight() - otherView.getHeight());
heightAnim.setDuration(1000);
view.startAnimation(heightAnim);
#10 楼
我改编了汤姆·埃斯特雷兹(Tom Esterez)当前接受的答案,该答案虽然有效,但动画不连贯且不稳定。我的解决方案基本上是将Animation
替换为ValueAnimator
,它可以与您选择的Interpolator
配合使用,以实现各种效果,例如过冲,反弹,加速等。此解决方案非常适合具有动态高度(即使用
WRAP_CONTENT
),因为它首先测量实际所需的高度,然后动画到该高度。 public static void expand(final View v) {
v.measure(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
final int targetHeight = v.getMeasuredHeight();
// Older versions of android (pre API 21) cancel animations for views with a height of 0.
v.getLayoutParams().height = 1;
v.setVisibility(View.VISIBLE);
ValueAnimator va = ValueAnimator.ofInt(1, targetHeight);
va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
v.getLayoutParams().height = (Integer) animation.getAnimatedValue();
v.requestLayout();
}
});
va.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationEnd(Animator animation) {
v.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT;
}
@Override public void onAnimationStart(Animator animation) {}
@Override public void onAnimationCancel(Animator animation) {}
@Override public void onAnimationRepeat(Animator animation) {}
});
va.setDuration(300);
va.setInterpolator(new OvershootInterpolator());
va.start();
}
public static void collapse(final View v) {
final int initialHeight = v.getMeasuredHeight();
ValueAnimator va = ValueAnimator.ofInt(initialHeight, 0);
va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
v.getLayoutParams().height = (Integer) animation.getAnimatedValue();
v.requestLayout();
}
});
va.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationEnd(Animator animation) {
v.setVisibility(View.GONE);
}
@Override public void onAnimationStart(Animator animation) {}
@Override public void onAnimationCancel(Animator animation) {}
@Override public void onAnimationRepeat(Animator animation) {}
});
va.setDuration(300);
va.setInterpolator(new DecelerateInterpolator());
va.start();
}
然后您只需致电
expand( myView );
或collapse( myView );
。评论
谢谢。您还可以添加最小高度不为0的情况。
– CoolMind
19年4月30日在14:50
刚刚更正了v.measure()中使用的参数,现在它可以正常工作。谢谢!
– Shahood ul Hassan
5月9日6:20
展开时振动视图
–阿布·纳耶姆(Abu Nayem)
10月6日下午16:25
#11 楼
利用Kotlin扩展功能,该功能已经过测试,答案最短只需在任何视图上调用animateVisibility(展开/折叠)即可。
fun View.animateVisibility(setVisible: Boolean) {
if (setVisible) expand(this) else collapse(this)
}
private fun expand(view: View) {
view.measure(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
val initialHeight = 0
val targetHeight = view.measuredHeight
// Older versions of Android (pre API 21) cancel animations for views with a height of 0.
//v.getLayoutParams().height = 1;
view.layoutParams.height = 0
view.visibility = View.VISIBLE
animateView(view, initialHeight, targetHeight)
}
private fun collapse(view: View) {
val initialHeight = view.measuredHeight
val targetHeight = 0
animateView(view, initialHeight, targetHeight)
}
private fun animateView(v: View, initialHeight: Int, targetHeight: Int) {
val valueAnimator = ValueAnimator.ofInt(initialHeight, targetHeight)
valueAnimator.addUpdateListener { animation ->
v.layoutParams.height = animation.animatedValue as Int
v.requestLayout()
}
valueAnimator.addListener(object : Animator.AnimatorListener {
override fun onAnimationEnd(animation: Animator) {
v.layoutParams.height = targetHeight
}
override fun onAnimationStart(animation: Animator) {}
override fun onAnimationCancel(animation: Animator) {}
override fun onAnimationRepeat(animation: Animator) {}
})
valueAnimator.duration = 300
valueAnimator.interpolator = DecelerateInterpolator()
valueAnimator.start()
}
评论
想要发布相同的答案:)太可惜了,这里太深了。
–muetzenflo
19年5月30日在10:44
@muetzenflo如果越来越多的人支持答案,它将出现。 :)
–拉吉兰
19年5月30日在11:26
我喜欢这种解决方案,直到我意识到如果有一个textview包含多行高度为wrap_content的行,展开时,textview将只显示一行。我正在尝试修复
–詹姆斯
19-10-18在13:08
我试过了,但是动画看起来不流畅。为了进行扩展,整个文本视图会短暂出现一次,然后播放动画。对于折叠,由于某种原因,textview在折叠后立即立即再次展开。知道我在做什么错吗?
–安吉思·阿查里亚(Anchith Acharya)
6月11日19:05
#12 楼
除了汤姆·埃斯特雷斯(Tom Esterez)的出色回答和埃里克·B(Erik B)的出色更新之外,我还想发表自己的看法,将扩展和收缩方法合并为一个。这样,您可以例如执行以下操作...button.setOnClickListener(v -> expandCollapse(view));
onClick()...
public static void expandCollapse(View view) {
boolean expand = view.getVisibility() == View.GONE;
Interpolator easeInOutQuart = PathInterpolatorCompat.create(0.77f, 0f, 0.175f, 1f);
view.measure(
View.MeasureSpec.makeMeasureSpec(((View) view.getParent()).getWidth(), View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
);
int height = view.getMeasuredHeight();
int duration = (int) (height/view.getContext().getResources().getDisplayMetrics().density);
Animation animation = new Animation() {
@Override protected void applyTransformation(float interpolatedTime, Transformation t) {
if (expand) {
view.getLayoutParams().height = 1;
view.setVisibility(View.VISIBLE);
if (interpolatedTime == 1) {
view.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT;
} else {
view.getLayoutParams().height = (int) (height * interpolatedTime);
}
view.requestLayout();
} else {
if (interpolatedTime == 1) {
view.setVisibility(View.GONE);
} else {
view.getLayoutParams().height = height - (int) (height * interpolatedTime);
view.requestLayout();
}
}
}
@Override public boolean willChangeBounds() {
return true;
}
};
animation.setInterpolator(easeInOutQuart);
animation.setDuration(duration);
view.startAnimation(animation);
}
评论
我尝试了此代码,但要使其在多个视图上工作,则必须滚动。知道我该如何解决吗? stackoverflow.com/q/43916369/1009507
–sammyukavi
17年5月11日在13:17
@Ukavi我在多个视图中使用它,并且在ScrollView中可以正常工作。
–mjp66
17年5月12日在7:16
在recyclerview中呢?
–sammyukavi
17年5月12日在14:20
@Ukavi还不需要在recyclerview中使用它,但是我不明白为什么它不起作用。您必须自己尝试一下;)
–mjp66
17年5月13日在9:50
#13 楼
我想在上面的非常有用的答案中添加一些内容。如果您不知道高度,因为视图.getHeight()返回0,则可以执行以下操作来获取高度:contentView.measure(DUMMY_HIGH_DIMENSION, DUMMY_HIGH_DIMENSION);
int finalHeight = view.getMeasuredHeight();
其中DUMMY_HIGH_DIMENSIONS是您的视图的宽度/高度(以像素为单位),当使用ScrollView封装视图时,拥有一个很大的数字是合理的。
#14 楼
这是我用来通过动画调整视图(LinearLayout)宽度的代码段。代码应该根据目标大小进行扩展或收缩。如果需要fill_parent宽度,则必须将父.getMeasuredWidth设置为目标宽度,同时将标志设置为true。
希望对您有所帮助。
}
评论
有什么技巧可以使它正常工作吗?该类将获得正确的原始宽度和目标宽度,但是我的视图不会调整大小。我正在使用resizeAnim.start()。也尝试过有和没有setFillAfter(true)
–本·凯恩(Ben Kane)
13年8月19日在21:58
得到它了。必须在视图上调用.startAnimation(resizeAnim)。
–本·凯恩(Ben Kane)
13年8月19日在22:02
#15 楼
对于平滑动画,请使用带有run方法的Handler。....并享受Expand / Collapse animation class AnimUtils{
public void expand(final View v) {
int ANIMATION_DURATION=500;//in milisecond
v.measure(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
final int targtetHeight = v.getMeasuredHeight();
v.getLayoutParams().height = 0;
v.setVisibility(View.VISIBLE);
Animation a = new Animation()
{
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
v.getLayoutParams().height = interpolatedTime == 1
? LayoutParams.WRAP_CONTENT
: (int)(targtetHeight * interpolatedTime);
v.requestLayout();
}
@Override
public boolean willChangeBounds() {
return true;
}
};
// 1dp/ms
a.setDuration(ANIMATION_DURATION);
// a.setDuration((int)(targtetHeight / v.getContext().getResources().getDisplayMetrics().density));
v.startAnimation(a);
}
public void collapse(final View v) {
final int initialHeight = v.getMeasuredHeight();
Animation a = new Animation()
{
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
if(interpolatedTime == 1){
v.setVisibility(View.GONE);
}else{
v.getLayoutParams().height = initialHeight - (int)(initialHeight * interpolatedTime);
v.requestLayout();
}
}
@Override
public boolean willChangeBounds() {
return true;
}
};
// 1dp/ms
a.setDuration(ANIMATION_DURATION);
// a.setDuration((int)(initialHeight / v.getContext().getResources().getDisplayMetrics().density));
v.startAnimation(a);
}
}
并使用以下代码调用:
private void setAnimationOnView(final View inactive ) {
//I am applying expand and collapse on this TextView ...You can use your view
//for expand animation
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
new AnimationUtililty().expand(inactive);
}
}, 1000);
//For collapse
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
new AnimationUtililty().collapse(inactive);
//inactive.setVisibility(View.GONE);
}
}, 8000);
}
其他解决方案是:
public void expandOrCollapse(final View v,String exp_or_colpse) {
TranslateAnimation anim = null;
if(exp_or_colpse.equals("expand"))
{
anim = new TranslateAnimation(0.0f, 0.0f, -v.getHeight(), 0.0f);
v.setVisibility(View.VISIBLE);
}
else{
anim = new TranslateAnimation(0.0f, 0.0f, 0.0f, -v.getHeight());
AnimationListener collapselistener= new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationRepeat(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
v.setVisibility(View.GONE);
}
};
anim.setAnimationListener(collapselistener);
}
// To Collapse
//
anim.setDuration(300);
anim.setInterpolator(new AccelerateInterpolator(0.5f));
v.startAnimation(anim);
}
#16 楼
是的,我同意以上评论。实际上,似乎正确(或至少最简单的方法)是(在XML中)指定初始布局高度“ 0px”-然后您可以为“ toHeight”传递另一个参数(您的自定义动画子类的构造函数的“最终高度”),例如在上面的示例中,它看起来像这样: public DropDownAnim( View v, int toHeight ) { ... }
无论如何,希望对您有所帮助! :)
#17 楼
这是我的解决方案。我认为这更简单。它只会扩展视图,但可以轻松扩展。public class WidthExpandAnimation extends Animation
{
int _targetWidth;
View _view;
public WidthExpandAnimation(View view)
{
_view = view;
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t)
{
if (interpolatedTime < 1.f)
{
int newWidth = (int) (_targetWidth * interpolatedTime);
_view.layout(_view.getLeft(), _view.getTop(),
_view.getLeft() + newWidth, _view.getBottom());
}
else
_view.requestLayout();
}
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight)
{
super.initialize(width, height, parentWidth, parentHeight);
_targetWidth = width;
}
@Override
public boolean willChangeBounds() {
return true;
}
}
#18 楼
我认为最简单的解决方案是将android:animateLayoutChanges="true"
设置为您的LinearLayout
,然后通过设置其可见性仅显示/隐藏视图。像吊饰一样工作,但您无法控制动画的持续时间#19 楼
@Tom Esterez和@Geraldo Neto的组合解决方案public static void expandOrCollapseView(View v,boolean expand){
if(expand){
v.measure(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT);
final int targetHeight = v.getMeasuredHeight();
v.getLayoutParams().height = 0;
v.setVisibility(View.VISIBLE);
ValueAnimator valueAnimator = ValueAnimator.ofInt(targetHeight);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
v.getLayoutParams().height = (int) animation.getAnimatedValue();
v.requestLayout();
}
});
valueAnimator.setInterpolator(new DecelerateInterpolator());
valueAnimator.setDuration(500);
valueAnimator.start();
}
else
{
final int initialHeight = v.getMeasuredHeight();
ValueAnimator valueAnimator = ValueAnimator.ofInt(initialHeight,0);
valueAnimator.setInterpolator(new DecelerateInterpolator());
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
v.getLayoutParams().height = (int) animation.getAnimatedValue();
v.requestLayout();
if((int)animation.getAnimatedValue() == 0)
v.setVisibility(View.GONE);
}
});
valueAnimator.setInterpolator(new DecelerateInterpolator());
valueAnimator.setDuration(500);
valueAnimator.start();
}
}
//sample usage
expandOrCollapseView((Your ViewGroup),(Your ViewGroup).getVisibility()!=View.VISIBLE);
#20 楼
您走在正确的轨道上。确保在动画开始之前将v1的布局高度设置为零。您希望在开始动画之前将设置初始化为看起来像动画的第一帧。评论
我同意,但是如果这样做,如何获取initialHeight(动画所需)?
–汤姆·埃斯特雷斯(Tom Esterez)
2011年2月9日15:39
您是否尝试过实际上只是将初始高度保存在Initialize中,将视图设置为可见,然后设置v.getLayoutParams()。height = 0 ;?直接之后,全部在初始化吗?
– Micah Hainline
2011年2月9日在20:12
是的,如果我这样做,则初始化方法的高度为0
–汤姆·埃斯特雷斯(Tom Esterez)
2011年2月9日在21:02
#21 楼
这是我的解决方法,我的ImageView
从100%
增长到200%
,并使用res/anim/
文件夹中的两个动画文件恢复到其原始大小。anim_grow.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_interpolator">
<scale
android:fromXScale="1.0"
android:toXScale="2.0"
android:fromYScale="1.0"
android:toYScale="2.0"
android:duration="3000"
android:pivotX="50%"
android:pivotY="50%"
android:startOffset="2000" />
</set>
anim_shrink.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_interpolator">
<scale
android:fromXScale="2.0"
android:toXScale="1.0"
android:fromYScale="2.0"
android:toYScale="1.0"
android:duration="3000"
android:pivotX="50%"
android:pivotY="50%"
android:startOffset="2000" />
</set>
将
ImageView
发送到我的方法setAnimationGrowShrink()
ImageView img1 = (ImageView)findViewById(R.id.image1);
setAnimationGrowShrink(img1);
setAnimationGrowShrink()
方法:private void setAnimationGrowShrink(final ImageView imgV){
final Animation animationEnlarge = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.anim_grow);
final Animation animationShrink = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.anim_shrink);
imgV.startAnimation(animationEnlarge);
animationEnlarge.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {}
@Override
public void onAnimationRepeat(Animation animation) {}
@Override
public void onAnimationEnd(Animation animation) {
imgV.startAnimation(animationShrink);
}
});
animationShrink.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {}
@Override
public void onAnimationRepeat(Animation animation) {}
@Override
public void onAnimationEnd(Animation animation) {
imgV.startAnimation(animationEnlarge);
}
});
}
#22 楼
这是一个正确的工作解决方案,我已经对其进行了测试:扩展名:
private void expand(View v) {
v.setVisibility(View.VISIBLE);
v.measure(View.MeasureSpec.makeMeasureSpec(PARENT_VIEW.getWidth(), View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
final int targetHeight = v.getMeasuredHeight();
mAnimator = slideAnimator(0, targetHeight);
mAnimator.setDuration(800);
mAnimator.start();
}
崩溃:
private void collapse(View v) {
int finalHeight = v.getHeight();
mAnimator = slideAnimator(finalHeight, 0);
mAnimator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animator) {
}
@Override
public void onAnimationEnd(Animator animator) {
//Height=0, but it set visibility to GONE
llDescp.setVisibility(View.GONE);
}
@Override
public void onAnimationCancel(Animator animator) {
}
@Override
public void onAnimationRepeat(Animator animator) {
}
});
mAnimator.start();
}
值动画师:
private ValueAnimator slideAnimator(int start, int end) {
ValueAnimator mAnimator = ValueAnimator.ofInt(start, end);
mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
//Update Height
int value = (Integer) valueAnimator.getAnimatedValue();
ViewGroup.LayoutParams layoutParams = llDescp.getLayoutParams();
layoutParams.height = value;
v.setLayoutParams(layoutParams);
}
});
return mAnimator;
}
视图v是要进行动画处理的视图,PARENT_VIEW是包含该视图的容器视图。
#23 楼
使用droidQuery确实很简单。首先,请考虑以下布局:<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<LinearLayout
android:id="@+id/v1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="View 1" />
</LinearLayout>
<LinearLayout
android:id="@+id/v2"
android:layout_width="wrap_content"
android:layout_height="0dp" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="View 2" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="View 3" />
</LinearLayout>
</LinearLayout>
我们可以使用以下代码将高度动画化为所需的值-例如
100dp
-://convert 100dp to pixel value
int height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 100, getResources().getDisplayMetrics());
然后使用
droidQuery
进行动画处理。最简单的方法是:$.animate("{ height: " + height + "}", new AnimationOptions());
要使动画更具吸引力,请考虑添加缓动:
$.animate("{ height: " + height + "}", new AnimationOptions().easing($.Easing.BOUNCE));
您还可以使用
AnimationOptions
方法更改duration()
上的持续时间,或处理动画结束时发生的情况。对于复杂的示例,请尝试:$.animate("{ height: " + height + "}", new AnimationOptions().easing($.Easing.BOUNCE)
.duration(1000)
.complete(new Function() {
@Override
public void invoke($ d, Object... args) {
$.toast(context, "finished", Toast.LENGTH_SHORT);
}
}));
#24 楼
展开/折叠视图的最佳解决方案: @Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
View view = buttonView.getId() == R.id.tb_search ? fSearch : layoutSettings;
transform(view, 200, isChecked
? ViewGroup.LayoutParams.WRAP_CONTENT
: 0);
}
public static void transform(final View v, int duration, int targetHeight) {
int prevHeight = v.getHeight();
v.setVisibility(View.VISIBLE);
ValueAnimator animator;
if (targetHeight == ViewGroup.LayoutParams.WRAP_CONTENT) {
v.measure(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
animator = ValueAnimator.ofInt(prevHeight, v.getMeasuredHeight());
} else {
animator = ValueAnimator.ofInt(prevHeight, targetHeight);
}
animator.addUpdateListener(animation -> {
v.getLayoutParams().height = (animation.getAnimatedFraction() == 1.0f)
? targetHeight
: (int) animation.getAnimatedValue();
v.requestLayout();
});
animator.setInterpolator(new LinearInterpolator());
animator.setDuration(duration);
animator.start();
}
评论
尽管有效,但它还取决于开发人员设置(动画持续时间)。并完善您的代码,删除lambda函数并重新格式化onCheckedChanged。
– CoolMind
16年7月29日在20:47
为什么在更改v的LayoutParams之后仅在v上调用requestLayout就足够了?我认为有必要在v的父级上调用requestLayout
–vlazzle
17年8月25日在7:43
#25 楼
您可以稍微扭转一下使用ViewPropertyAnimator。要折叠,请将视图缩放到1个像素的高度,然后将其隐藏。要展开,请显示它,然后将其展开到其高度。private void collapse(final View view) {
view.setPivotY(0);
view.animate().scaleY(1/view.getHeight()).setDuration(1000).withEndAction(new Runnable() {
@Override public void run() {
view.setVisibility(GONE);
}
});
}
private void expand(View view, int height) {
float scaleFactor = height / view.getHeight();
view.setVisibility(VISIBLE);
view.setPivotY(0);
view.animate().scaleY(scaleFactor).setDuration(1000);
}
枢轴告诉视图缩放的位置,默认位置在中间。持续时间是可选的(默认= 1000)。您还可以设置要使用的插值器,例如
.setInterpolator(new AccelerateDecelerateInterpolator())
#26 楼
基于@Tom Esterez和@Seth Nelson(排名前2)的解决方案,我对其进行了简化。与原始解决方案一样,它也不依赖于开发人员选项(动画设置)。private void resizeWithAnimation(final View view, int duration, final int targetHeight) {
final int initialHeight = view.getMeasuredHeight();
final int distance = targetHeight - initialHeight;
view.setVisibility(View.VISIBLE);
Animation a = new Animation() {
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
if (interpolatedTime == 1 && targetHeight == 0) {
view.setVisibility(View.GONE);
}
view.getLayoutParams().height = (int) (initialHeight + distance * interpolatedTime);
view.requestLayout();
}
@Override
public boolean willChangeBounds() {
return true;
}
};
a.setDuration(duration);
view.startAnimation(a);
}
评论
好了,三年后,我再次测试了几种解决方案,但只有我的解决方案正确。
– CoolMind
19年4月30日在15:25
#27 楼
我创建了不需要指定布局高度的版本,因此它使用起来更容易,更清洁。解决方案是在动画的第一帧中获取高度(当时至少在我的测试中可用)。这样,您就可以为View提供任意高度和底边距。构造函数中还有一个小技巧-底边距设置为-10000,以便在转换前视图保持隐藏状态(防止闪烁)。
public class ExpandAnimation extends Animation {
private View mAnimatedView;
private ViewGroup.MarginLayoutParams mViewLayoutParams;
private int mMarginStart, mMarginEnd;
public ExpandAnimation(View view) {
mAnimatedView = view;
mViewLayoutParams = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
mMarginEnd = mViewLayoutParams.bottomMargin;
mMarginStart = -10000; //hide before viewing by settings very high negative bottom margin (hack, but works nicely)
mViewLayoutParams.bottomMargin = mMarginStart;
mAnimatedView.setLayoutParams(mViewLayoutParams);
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
super.applyTransformation(interpolatedTime, t);
//view height is already known when the animation starts
if(interpolatedTime==0){
mMarginStart = -mAnimatedView.getHeight();
}
mViewLayoutParams.bottomMargin = (int)((mMarginEnd-mMarginStart) * interpolatedTime)+mMarginStart;
mAnimatedView.setLayoutParams(mViewLayoutParams);
}
}
#28 楼
使用ValueAnimator:ValueAnimator expandAnimation = ValueAnimator.ofInt(mainView.getHeight(), 400);
expandAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(final ValueAnimator animation) {
int height = (Integer) animation.getAnimatedValue();
RelativeLayout.LayoutParams lp = (LayoutParams) mainView.getLayoutParams();
lp.height = height;
}
});
expandAnimation.setDuration(500);
expandAnimation.start();
评论
就我而言,什么都不做。您也可以简化代码,将2行折叠成mainView.getLayoutParams()。height = height。
– CoolMind
16年7月29日在20:34
#29 楼
public static void slide(View v, int speed, int pos) {
v.animate().setDuration(speed);
v.animate().translationY(pos);
v.animate().start();
}
// slide down
slide(yourView, 250, yourViewHeight);
// slide up
slide(yourView, 250, 0);
#30 楼
/**
* Animation that either expands or collapses a view by sliding it down to make
* it visible. Or by sliding it up so it will hide. It will look like it slides
* behind the view above.
*
*/
public class FinalExpandCollapseAnimation extends Animation
{
private View mAnimatedView;
private int mEndHeight;
private int mType;
public final static int COLLAPSE = 1;
public final static int EXPAND = 0;
private LinearLayout.LayoutParams mLayoutParams;
private RelativeLayout.LayoutParams mLayoutParamsRel;
private String layout;
private Context context;
/**
* Initializes expand collapse animation, has two types, collapse (1) and
* expand (0).
*
* @param view
* The view to animate
* @param type
* The type of animation: 0 will expand from gone and 0 size to
* visible and layout size defined in xml. 1 will collapse view
* and set to gone
*/
public FinalExpandCollapseAnimation(View view, int type, int height, String layout, Context context)
{
this.layout = layout;
this.context = context;
mAnimatedView = view;
mEndHeight = mAnimatedView.getMeasuredHeight();
if (layout.equalsIgnoreCase("linear"))
mLayoutParams = ((LinearLayout.LayoutParams) view.getLayoutParams());
else
mLayoutParamsRel = ((RelativeLayout.LayoutParams) view.getLayoutParams());
mType = type;
if (mType == EXPAND)
{
AppConstant.ANIMATED_VIEW_HEIGHT = height;
}
else
{
if (layout.equalsIgnoreCase("linear"))
mLayoutParams.topMargin = 0;
else
mLayoutParamsRel.topMargin = convertPixelsIntoDensityPixels(36);
}
setDuration(600);
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t)
{
super.applyTransformation(interpolatedTime, t);
if (interpolatedTime < 1.0f)
{
if (mType == EXPAND)
{
if (layout.equalsIgnoreCase("linear"))
{
mLayoutParams.height = AppConstant.ANIMATED_VIEW_HEIGHT
+ (-AppConstant.ANIMATED_VIEW_HEIGHT + (int) (AppConstant.ANIMATED_VIEW_HEIGHT * interpolatedTime));
}
else
{
mLayoutParamsRel.height = AppConstant.ANIMATED_VIEW_HEIGHT
+ (-AppConstant.ANIMATED_VIEW_HEIGHT + (int) (AppConstant.ANIMATED_VIEW_HEIGHT * interpolatedTime));
}
mAnimatedView.setVisibility(View.VISIBLE);
}
else
{
if (layout.equalsIgnoreCase("linear"))
mLayoutParams.height = mEndHeight - (int) (mEndHeight * interpolatedTime);
else
mLayoutParamsRel.height = mEndHeight - (int) (mEndHeight * interpolatedTime);
}
mAnimatedView.requestLayout();
}
else
{
if (mType == EXPAND)
{
if (layout.equalsIgnoreCase("linear"))
{
mLayoutParams.height = AppConstant.ANIMATED_VIEW_HEIGHT;
mLayoutParams.topMargin = 0;
}
else
{
mLayoutParamsRel.height = AppConstant.ANIMATED_VIEW_HEIGHT;
mLayoutParamsRel.topMargin = convertPixelsIntoDensityPixels(36);
}
mAnimatedView.setVisibility(View.VISIBLE);
mAnimatedView.requestLayout();
}
else
{
if (layout.equalsIgnoreCase("linear"))
mLayoutParams.height = 0;
else
mLayoutParamsRel.height = 0;
mAnimatedView.setVisibility(View.GONE);
mAnimatedView.requestLayout();
}
}
}
private int convertPixelsIntoDensityPixels(int pixels)
{
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
return (int) metrics.density * pixels;
}
}
可以按以下方式调用该类
if (findViewById(R.id.ll_specailoffer_show_hide).getVisibility() == View.VISIBLE) {
((ImageView) findViewById(R.id.iv_specialhour_seemore)).setImageResource(R.drawable.white_dropdown_up);
FinalExpandCollapseAnimation finalExpandCollapseAnimation = new FinalExpandCollapseAnimation(
findViewById(R.id.ll_specailoffer_show_hide),
FinalExpandCollapseAnimation.COLLAPSE,
SpecialOfferHeight, "linear", this);
findViewById(R.id.ll_specailoffer_show_hide)
.startAnimation(finalExpandCollapseAnimation);
((View) findViewById(R.id.ll_specailoffer_show_hide).getParent()).invalidate();
} else {
((ImageView) findViewById(R.id.iv_specialhour_seemore)).setImageResource(R.drawable.white_dropdown);
FinalExpandCollapseAnimation finalExpandCollapseAnimation = new FinalExpandCollapseAnimation(
findViewById(R.id.ll_specailoffer_show_hide),
FinalExpandCollapseAnimation.EXPAND,
SpecialOfferHeight, "linear", this);
findViewById(R.id.ll_specailoffer_show_hide)
.startAnimation(finalExpandCollapseAnimation);
((View) findViewById(R.id.ll_specailoffer_show_hide).getParent()).invalidate();
}
评论
这个问题的最高答案仍然是闪光灯的相同问题