如何为View.setVisibility(GONE)设置动画

MrS*_*ake 84 animation android

我希望AnimationView将其可见性设置为时进行制作GONE.View应该"崩溃" ,而不仅仅是消失.我尝试了这个ScaleAnimation但是然后View是崩溃,但布局只会在Animation停止(或开始)之后(或之前)调整它的空间.

我如何制作,Animation以便在制作动画时,较低的Views将直接保留在内容之下,而不是有空格?

Vin*_*hwa 98

如果视图不是,则将视图放在布局中,并android:animateLayoutChanges="true"为该布局设置.

  • 你好生活先生:) (2认同)
  • 这是最被低估的布局属性......谢谢! (2认同)

小智 51

似乎没有一种简单的方法可以通过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);
            }
        }

    }

}
Run Code Online (Sandbox Code Playgroud)

通常的警告适用:因为我们覆盖了受保护的方法(applyTransformation),所以不保证在未来的Android版本中可以使用.

  • 为什么地狱没有我想到这个?!谢谢.此外,我没有得到:"通常的警告适用:因为我们覆盖了受保护的方法(applyTransformation),所以不能保证在未来的Android版本中有效." - 为什么API版本之间受保护的功能不同?这些不是隐藏的,并且实现了受保护,以便您可以覆盖它们(否则它们将是包作用域). (3认同)
  • 假设我必须切换动画,那么怎么能反过来呢.请指教. (3认同)
  • 我建议使用泛型类型`MarginLayoutParams`而不是将其转换为特定的`LayoutParam`类型. (2认同)

Udi*_*nic 7

我使用的技术与安迪在这里提出的技术相同.我为此编写了自己的动画类,使边距的值动画化,导致项目的效果消失/出现.它看起来像这样:

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();
    }
}
}
Run Code Online (Sandbox Code Playgroud)

我有一个完整的例子,可以在我的博客上发表 http://udinic.wordpress.com/2011/09/03/expanding-listview-items/