Одна анимация - несколько просмотров - PullRequest
19 голосов
/ 09 февраля 2012

Есть ли способ анимировать несколько видов одновременно?

Я хочу перевести анимацию:

У меня есть 5 TextViews и 4 цветные полосы (простые RelativeLayouts с фоном). В начале анимации стипы располагаются вместе с TextViews в горизонтальном ряду. В конце я хочу, чтобы все TextViews были сложены между полосами:

enter image description here

Это очень простой рисунок, но он демонстрирует, что я хочу сделать. Есть ли способ сделать это с анимацией, или я должен использовать анимацию холста.

Ответы [ 4 ]

54 голосов
/ 22 ноября 2012

Вы можете использовать ObjectAnimator для анимации множественного представления следующим образом:

ArrayList<ObjectAnimator> arrayListObjectAnimators = new ArrayList<ObjectAnimator>(); //ArrayList of ObjectAnimators

ObjectAnimator animY = ObjectAnimator.ofFloat(view, "y", 100f);
arrayListObjectAnimators.add(animY);

ObjectAnimator animX = ObjectAnimator.ofFloat(view, "x", 0f);
arrayListObjectAnimators.add(animX);
...
ObjectAnimator[] objectAnimators = arrayListObjectAnimators.toArray(new ObjectAnimator[arrayListObjectAnimators.size()]);
AnimatorSet animSetXY = new AnimatorSet();
animSetXY.playTogether(objectAnimators);
animSetXY.setDuration(1000);//1sec
animSetXY.start();
4 голосов
/ 09 февраля 2012

Создайте свои объекты анимации, затем используйте startAnimation для всех видов одновременно. Так было бы что-то вроде этого:

TranslateAnimation anim1;
TranslateAnimation anim2;
TranslateAnimation anim3;

// Setup the animation objects

public void startAnimations()
{
   //... collect view objects
   view1.startAnimation(anim1);
   view2.startAnimation(anim2);
   view3.startAnimation(anim3);
}

Просто отметьте, что чем больше анимаций у вас одновременно, тем медленнее будет.

3 голосов
/ 11 декабря 2017

Вы можете использовать AnimationSet

AnimatorSet decSet2 = new AnimatorSet();
        decSet2.playTogether(
                ObjectAnimator.ofFloat(view, "x",dX),
                ObjectAnimator.ofFloat(view, "y",dY),
                ObjectAnimator.ofFloat(mTextCancel, "x",dX),
                ObjectAnimator.ofFloat(mTextCancel, "y", dY),
                ObjectAnimator.ofArgb(mBtnOne, "visibility", View.VISIBLE, View.GONE),
                );
        decSet2.setDuration(0);
        decSet2.start();
3 голосов
/ 26 июня 2012

Мне удалось разделить один экземпляр Animation между несколькими представлениями. По крайней мере, с AlphaAnimation. У меня был ListView и анимация, которая должна применяться к конкретному дочернему элементу всех представлений элементов списка. В моем случае, должно быть возможным, чтобы представления могли «присоединиться» и «покинуть» общую анимацию в любое время, и это никоим образом не должно влиять на другие анимированные виды или мешать уже запущенной анимации. Чтобы добиться этого, мне пришлось сделать скорректированную копию Android AlphaAnimation. Мой вариант использования довольно особенный, но пусть он будет здесь только на тот случай, если кому-то придется столкнуться с аналогичной целью с ListView.

/**
 * This class is a copy of android's stock AlphaAnimation with two adjustments:
 * - fromAlpha, toAlpha and duration are settable at any time.
 * - reset() method can be blocked. Reason: view.setAnimation() calls animation's reset() method
 * which is not intended in our use case.
 * For every new list item view we call setAnimation once for it's life time
 * and animation should not be reset because it is shared by all list item views and may be in progress. 
 */
public class MutableAlphaAnimation extends Animation {
    private float mFromAlpha;
    private float mToAlpha;
    private boolean resetBlocked;

    public MutableAlphaAnimation() {
    }

    public void start(float fromAlpha, float toAlpha, long duration) {
        mFromAlpha = fromAlpha;
        mToAlpha = toAlpha;
        setDuration(duration);
        setStartTime(START_ON_FIRST_FRAME);
    }

    public void setResetBlocked(boolean resetBlocked) {
        this.resetBlocked = resetBlocked;
    }

    @Override
    public void reset() {
        if (! resetBlocked) super.reset();
    }

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        final float alpha = mFromAlpha;
        t.setAlpha(alpha + ((mToAlpha - alpha) * interpolatedTime));
    }

    @Override
    public boolean willChangeTransformationMatrix() {
        return false;
    }

    @Override
    public boolean willChangeBounds() {
        return false;
    }
}

Чтобы установить анимацию для вида:

            animation.setResetBlocked(true);
            view.setAnimation(animation);
            animation.setResetBlocked(false);

И чтобы запустить анимацию (предварительно установленную setAnimation), нужно сделать ДВА:

        animation.start(0.0f, 1.0f, FADE_IN_DURATION);

И после этого вы должны вручную вызывать invalidate () для каждого представления, на которое влияет анимация.

Обычная функция startAnimation () делает тебя недействительной (), а setAnimation - нет. (читайте комментарий о методе View.setAnimation () в источниках Android).

...