我想在View
的可見性設置爲GONE
時設置Animation
。 View
不應該消失,而應該「崩潰」。我嘗試了ScaleAnimation
,但View
已崩潰,但佈局將僅在Animation
停止(或開始)之後(或之前)調整其空間大小。如何設置View.setVisibility的動畫
我該如何製作Animation
,以便在動畫製作時,較低的View
將保持在內容的正下方,而不是空白區域?
我想在View
的可見性設置爲GONE
時設置Animation
。 View
不應該消失,而應該「崩潰」。我嘗試了ScaleAnimation
,但View
已崩潰,但佈局將僅在Animation
停止(或開始)之後(或之前)調整其空間大小。如何設置View.setVisibility的動畫
我該如何製作Animation
,以便在動畫製作時,較低的View
將保持在內容的正下方,而不是空白區域?
似乎沒有一種簡單的方法可以通過API實現此目的,因爲動畫只會改變視圖的渲染矩陣,而不會改變實際大小。但是我們可以設置一個負邊界來讓LinearLayout認爲視圖變小。
所以我建議根據ScaleAnimation創建您自己的Animation類,並重寫「applyTransformation」方法來設置新的邊距並更新佈局。像這樣...
public class Q2634073 extends Activity implements OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.q2634073);
findViewById(R.id.item1).setOnClickListener(this);
}
@Override
public void onClick(View view) {
view.startAnimation(new MyScaler(1.0f, 1.0f, 1.0f, 0.0f, 500, view, true));
}
public class MyScaler extends ScaleAnimation {
private View mView;
private LayoutParams mLayoutParams;
private int mMarginBottomFromY, mMarginBottomToY;
private boolean mVanishAfter = false;
public MyScaler(float fromX, float toX, float fromY, float toY, int duration, View view,
boolean vanishAfter) {
super(fromX, toX, fromY, toY);
setDuration(duration);
mView = view;
mVanishAfter = vanishAfter;
mLayoutParams = (LayoutParams) view.getLayoutParams();
int height = mView.getHeight();
mMarginBottomFromY = (int) (height * fromY) + mLayoutParams.bottomMargin - height;
mMarginBottomToY = (int) (0 - ((height * toY) + mLayoutParams.bottomMargin)) - height;
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
super.applyTransformation(interpolatedTime, t);
if (interpolatedTime < 1.0f) {
int newMarginBottom = mMarginBottomFromY
+ (int) ((mMarginBottomToY - mMarginBottomFromY) * interpolatedTime);
mLayoutParams.setMargins(mLayoutParams.leftMargin, mLayoutParams.topMargin,
mLayoutParams.rightMargin, newMarginBottom);
mView.getParent().requestLayout();
} else if (mVanishAfter) {
mView.setVisibility(View.GONE);
}
}
}
}
通常的原則同樣適用:因爲我們覆蓋一個受保護的方法(applyTransformation),並不保證在Android的未來版本的工作。
爲什麼我沒有想到這個?謝謝。我也沒有得到:「通常的警告適用:因爲我們正在覆蓋受保護的方法(applyTransformation),所以這並不能保證在將來的Android版本中有效。」 - 爲什麼API版本的受保護功能會有所不同?這些不是隱藏的,並且實現了保護,以便您可以覆蓋它們(否則它們將成爲程序包範圍)。 – MrSnowflake 2010-10-18 17:16:16
對於受保護的方法您可能是正確的。我傾向於在API中訪問它們過於謹慎。 – Andy 2010-10-18 21:42:09
Atleast那麼你很確定API更新不會破壞你的應用程序:)。 – MrSnowflake 2010-10-19 13:53:05
我用了和Andy一樣的技巧。我爲此編寫了自己的動畫類,使邊距的值變爲動畫,從而使物品的效果消失/出現。 它看起來像這樣:
public class ExpandAnimation extends Animation {
// Initializations...
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
super.applyTransformation(interpolatedTime, t);
if (interpolatedTime < 1.0f) {
// Calculating the new bottom margin, and setting it
mViewLayoutParams.bottomMargin = mMarginStart
+ (int) ((mMarginEnd - mMarginStart) * interpolatedTime);
// Invalidating the layout, making us seeing the changes we made
mAnimatedView.requestLayout();
}
}
}
我有一個完整的例子,在我的博客文章作品 http://udinic.wordpress.com/2011/09/03/expanding-listview-items/
我用同樣的技術,因爲安迪在這裏,和完善它,以便它可以用於擴大和摺疊無毛刺,也利用這裏所描述的技術:https://stackoverflow.com/a/11426510/1317564
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.animation.ScaleAnimation;
import android.view.animation.Transformation;
import android.widget.LinearLayout;
class LinearLayoutVerticalScaleAnimation extends ScaleAnimation {
private final LinearLayout view;
private final LinearLayout.LayoutParams layoutParams;
private final float beginY;
private final float endY;
private final int originalBottomMargin;
private int expandedHeight;
private boolean marginsInitialized = false;
private int marginBottomBegin;
private int marginBottomEnd;
private ViewTreeObserver.OnPreDrawListener preDrawListener;
LinearLayoutVerticalScaleAnimation(float beginY, float endY,
LinearLayout linearLayout) {
super(1f, 1f, beginY, endY);
this.view = linearLayout;
this.layoutParams = (LinearLayout.LayoutParams) linearLayout.getLayoutParams();
this.beginY = beginY;
this.endY = endY;
this.originalBottomMargin = layoutParams.bottomMargin;
if (view.getHeight() != 0) {
expandedHeight = view.getHeight();
initializeMargins();
}
}
private void initializeMargins() {
final int beginHeight = (int) (expandedHeight * beginY);
final int endHeight = (int) (expandedHeight * endY);
marginBottomBegin = beginHeight + originalBottomMargin - expandedHeight;
marginBottomEnd = endHeight + originalBottomMargin - expandedHeight;
marginsInitialized = true;
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
super.applyTransformation(interpolatedTime, t);
if (!marginsInitialized && preDrawListener == null) {
// To avoid glitches, don't draw until we've initialized everything.
preDrawListener = new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
if (view.getHeight() != 0) {
expandedHeight = view.getHeight();
initializeMargins();
adjustViewBounds(0f);
view.getViewTreeObserver().removeOnPreDrawListener(this);
}
return false;
}
};
view.getViewTreeObserver().addOnPreDrawListener(preDrawListener);
}
if (interpolatedTime < 1.0f && view.getVisibility() != View.VISIBLE) {
view.setVisibility(View.VISIBLE);
}
if (marginsInitialized) {
if (interpolatedTime < 1.0f) {
adjustViewBounds(interpolatedTime);
} else if (endY <= 0f && view.getVisibility() != View.GONE) {
view.setVisibility(View.GONE);
}
}
}
private void adjustViewBounds(float interpolatedTime) {
layoutParams.bottomMargin =
marginBottomBegin + (int) ((marginBottomEnd - marginBottomBegin) * interpolatedTime);
view.getParent().requestLayout();
}
}
是否可以使用它來先摺疊現有的LinearLayout,然後再次展開同一個LinearLayout?當我嘗試這樣做時,它會崩潰並且不會再次展開(可能是因爲視圖的高度現在爲0或類似的值)。 – AHaahr 2013-06-27 21:50:54
當線性佈局包含多個視圖時,我發現它可以更可靠地工作。如果它只包含一個視圖,那麼它不會一直展開。 – 2013-08-13 19:58:19
把視圖中的佈局,如果它不是,並設置android:animateLayoutChanges="true"
該佈局。
最低API要求是11或更高!對於較低版本,不能使用此方法。 – 2014-10-19 07:06:04
你好Mr.Life :) – 2015-04-22 11:24:43
這是最被低估的佈局屬性......謝謝! – 2016-01-15 21:56:36
我已經使用了與Andy在這裏展示的技術相同的技術,在我的ExpandAnimation上: http://udinic.wordpress.com/2011/09/03/expanding-listview-items/我沒有使用我只是爲此構建了一個新的Animation類。 – Udinic 2011-09-03 22:14:15
這是非常有用的,當我試圖做到這一點。謝謝 – atraudes 2011-09-23 19:42:49
優秀的Udinic ..真的解決了我的問題.. :)謝謝 – 2011-11-22 14:20:46