次のような垂直の linearLayout があるとします。
[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 では、これは 1 行の 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 の速度に設定されています。