Android:展开/折叠动画
假设我有一个垂直线性布局:
[v1]
[v2]
默认情况下v1有visibily = 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?
我发现这个问题变得很流行,所以我发布了我的实际解决方案。 主要优点是您不必知道展开的高度以应用动画,并且一旦展开视图,就会在内容更改时调整高度。 这对我很有效。
public static void expand(final View v) {
v.measure(LayoutParams.MATCH_PARENT, 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);
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;
}
};
// 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;
}
};
// 1dp/ms
a.setDuration((int)(initialHeight / v.getContext().getResources().getDisplayMetrics().density));
v.startAnimation(a);
}
我试图做我认为是非常相似的动画,并找到了一个优雅的解决方案。 这段代码假定你总是从0-> h或h-> 0(h是最大高度)。 这三个构造函数参数是view =动画视图(在我的情况下是webview),targetHeight =视图的最大高度,down =指定方向的布尔值(true = expanded,false = collapsing)。
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;
}
}
我今天偶然发现了同样的问题,我猜这个问题的真正解决方案是这样的
<LinearLayout android:id="@+id/container"
android:animateLayoutChanges="true"
...
/>
您将不得不为该变化中涉及的所有最高布局设置此属性。 如果您现在将一个布局的可见性设置为GONE,另一个布局将消失的空间释放它。 将有一种默认动画是某种“淡出”,但我认为你可以改变这一点 - 但现在我还没有测试过最后一个。
链接地址: http://www.djcxy.com/p/84227.html