Android: dodaj widok z rozszerzeniem animacji (bez migania)

Chcę dodać widok do grupy widoków za pomocą rozwijającej się animacji, więc dodany widok zaczyna się bardzo mały i zajmuje coraz więcej miejsca, dopóki nie osiągnie pełnego rozmiaru (prawdopodobnie przenosząc inne widoki w procesie).

Po wypróbowaniu różnych podejść wpadłem na poniższe rozwiązanie. Głosuj, jeśli ci to pomoże lub napisz lepszą alternatywę. Jestem pewien, że musi to być łatwiejszy sposób.

Aby uzyskać więcej informacji, zobacz posty podobneten iten.

Oto, jak mogę dodać widok i rozpocząć animację:

// Trick: set height to 1 so the view doesn't take its full size at the beginning.
// (0 doesn't work, I don't know why)
container.addView(view, LayoutParams.MATCH_PARENT, 1);
Animation expansion = createExpansion(view);
expansion.setDuration(200);
view.startAnimation(expansion);

ThecreateExpansion() metoda:

public static Animation createExpansion(View view) {

    return new SizedHeightScaleAnimation(view, 0, 1,
            Animation.RELATIVE_TO_SELF, 0f,
            Animation.RELATIVE_TO_SELF, 0f);
}

I wreszcieSizedHeightScaleAnimation klasa animacji:

/**
 * Like {@link ScaleAnimation} for height scaling that also resizes the view accordingly,
 * so it takes the right amount of space while scaling.
 */
public class SizedHeightScaleAnimation extends ScaleAnimation {

    private float fromHeight;
    private float toHeight;
    private View viewToScale;

    public SizedHeightScaleAnimation(View viewToScale, float fromY, float toY) {
        super(1, 1, fromY, toY);
        init(viewToScale, fromY, toY);
    }

    public SizedHeightScaleAnimation(View viewToScale, float fromY, float toY, float pivotX, float pivotY) {
        super(1, 1, fromY, toY, pivotX, pivotY);
        init(viewToScale, fromY, toY);
    }

    public SizedHeightScaleAnimation(View viewToScale, float fromY, float toY, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue) {
        super(1, 1, fromY, toY, pivotXType, pivotXValue, pivotYType, pivotYValue);
        init(viewToScale, fromY, toY);
    }

    private void init(View viewToScale, float fromY, float toY) {

        this.viewToScale = viewToScale;
        viewToScale.measure(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
        fromHeight = viewToScale.getMeasuredHeight() * fromY;
        toHeight = viewToScale.getMeasuredHeight() * toY;
    }

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        super.applyTransformation(interpolatedTime, t);

        final int newHeight = (int) (fromHeight * (1 - interpolatedTime) + toHeight * interpolatedTime);

        viewToScale.getLayoutParams().height = newHeight;
        viewToScale.requestLayout();
    }
}

Nawiasem mówiąc, możesz w ten sposób stworzyć efekt upadku:

public static Animation createCollapse(View view) {

    return new SizedHeightScaleAnimation(view, 1, 0,
            Animation.RELATIVE_TO_SELF, 0f,
            Animation.RELATIVE_TO_SELF, 0f);
}

Gdy go użyjesz, prawdopodobnie będziesz chciał usunąć widok od rodzica, gdy animacja zostanie wykonana:

Animation collapse = createCollapse(view);
collapse.setDuration(200);

collapse.setAnimationListener(new AnimationListener() {
    @Override
    public void onAnimationEnd(Animation animation) {
        final ViewGroup parent = (ViewGroup) view.getParent();
        parent.removeView(view);
    }

    ... other overrides ...
});

view.startAnimation(collapse);

questionAnswers(1)

yourAnswerToTheQuestion