115a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi/*
25673353559453ecb57fc767b4e7500dd46e44079Jorim Jaggi * Copyright (C) 2015 The Android Open Source Project
315a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi *
415a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi * Licensed under the Apache License, Version 2.0 (the "License");
515a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi * you may not use this file except in compliance with the License.
615a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi * You may obtain a copy of the License at
715a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi *
815a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi *      http://www.apache.org/licenses/LICENSE-2.0
915a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi *
1015a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi * Unless required by applicable law or agreed to in writing, software
1115a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi * distributed under the License is distributed on an "AS IS" BASIS,
1215a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1315a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi * See the License for the specific language governing permissions and
1415a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi * limitations under the License
1515a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi */
1615a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi
175673353559453ecb57fc767b4e7500dd46e44079Jorim Jaggipackage com.android.settingslib.animation;
1815a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi
19613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggiimport android.animation.Animator;
20613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggiimport android.animation.AnimatorListenerAdapter;
21613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggiimport android.animation.ObjectAnimator;
22613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggiimport android.animation.ValueAnimator;
2315a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggiimport android.content.Context;
24613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggiimport android.view.RenderNodeAnimator;
2515a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggiimport android.view.View;
26613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggiimport android.view.ViewPropertyAnimator;
2715a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggiimport android.view.animation.AnimationUtils;
2815a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggiimport android.view.animation.Interpolator;
2915a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi
30613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggiimport com.android.internal.widget.LockPatternView;
315673353559453ecb57fc767b4e7500dd46e44079Jorim Jaggiimport com.android.settingslib.R;
325673353559453ecb57fc767b4e7500dd46e44079Jorim Jaggi
3315a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi/**
3415a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi * A class to make nice appear transitions for views in a tabular layout.
3515a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi */
363018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinekpublic class AppearAnimationUtils implements AppearAnimationCreator<View> {
3715a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi
3898f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi    public static final long DEFAULT_APPEAR_DURATION = 220;
3915a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi
4098f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi    private final Interpolator mInterpolator;
4115a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi    private final float mStartTranslation;
423018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek    private final AppearAnimationProperties mProperties = new AppearAnimationProperties();
43f9c0e8f02f3483d6aa9e762c97a2c02ea50eeb02Selim Cinek    protected final float mDelayScale;
4498f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi    private final long mDuration;
455673353559453ecb57fc767b4e7500dd46e44079Jorim Jaggi    protected RowTranslationScaler mRowTranslationScaler;
46f9c0e8f02f3483d6aa9e762c97a2c02ea50eeb02Selim Cinek    protected boolean mAppearing;
4715a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi
4815a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi    public AppearAnimationUtils(Context ctx) {
4998f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi        this(ctx, DEFAULT_APPEAR_DURATION,
5076a1623afc170a13923b68f3256057d8adeb7937Jorim Jaggi                1.0f, 1.0f,
5198f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi                AnimationUtils.loadInterpolator(ctx, android.R.interpolator.linear_out_slow_in));
523018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek    }
533018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek
5498f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi    public AppearAnimationUtils(Context ctx, long duration, float translationScaleFactor,
5598f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi            float delayScaleFactor, Interpolator interpolator) {
5698f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi        mInterpolator = interpolator;
573018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek        mStartTranslation = ctx.getResources().getDimensionPixelOffset(
583018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek                R.dimen.appear_y_translation_start) * translationScaleFactor;
593018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek        mDelayScale = delayScaleFactor;
6098f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi        mDuration = duration;
61f9c0e8f02f3483d6aa9e762c97a2c02ea50eeb02Selim Cinek        mAppearing = true;
6215a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi    }
6315a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi
645673353559453ecb57fc767b4e7500dd46e44079Jorim Jaggi    public void startAnimation2d(View[][] objects, final Runnable finishListener) {
655673353559453ecb57fc767b4e7500dd46e44079Jorim Jaggi        startAnimation2d(objects, finishListener, this);
663018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek    }
673018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek
68f9c0e8f02f3483d6aa9e762c97a2c02ea50eeb02Selim Cinek    public void startAnimation(View[] objects, final Runnable finishListener) {
69f9c0e8f02f3483d6aa9e762c97a2c02ea50eeb02Selim Cinek        startAnimation(objects, finishListener, this);
7098f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi    }
7198f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi
725673353559453ecb57fc767b4e7500dd46e44079Jorim Jaggi    public <T> void startAnimation2d(T[][] objects, final Runnable finishListener,
733018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek            AppearAnimationCreator<T> creator) {
743018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek        AppearAnimationProperties properties = getDelays(objects);
753018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek        startAnimations(properties, objects, finishListener, creator);
763018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek    }
773018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek
78f9c0e8f02f3483d6aa9e762c97a2c02ea50eeb02Selim Cinek    public <T> void startAnimation(T[] objects, final Runnable finishListener,
7998f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi            AppearAnimationCreator<T> creator) {
8098f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi        AppearAnimationProperties properties = getDelays(objects);
8198f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi        startAnimations(properties, objects, finishListener, creator);
8298f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi    }
8398f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi
8498f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi    private <T> void startAnimations(AppearAnimationProperties properties, T[] objects,
8598f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi            final Runnable finishListener, AppearAnimationCreator<T> creator) {
8698f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi        if (properties.maxDelayRowIndex == -1 || properties.maxDelayColIndex == -1) {
8798f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi            finishListener.run();
8898f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi            return;
8998f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi        }
9098f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi        for (int row = 0; row < properties.delays.length; row++) {
9198f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi            long[] columns = properties.delays[row];
9298f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi            long delay = columns[0];
9398f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi            Runnable endRunnable = null;
9498f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi            if (properties.maxDelayRowIndex == row && properties.maxDelayColIndex == 0) {
9598f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi                endRunnable = finishListener;
9698f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi            }
975673353559453ecb57fc767b4e7500dd46e44079Jorim Jaggi            float translationScale = mRowTranslationScaler != null
985673353559453ecb57fc767b4e7500dd46e44079Jorim Jaggi                    ? mRowTranslationScaler.getRowTranslationScale(row, properties.delays.length)
995673353559453ecb57fc767b4e7500dd46e44079Jorim Jaggi                    : 1f;
1005673353559453ecb57fc767b4e7500dd46e44079Jorim Jaggi            float translation = translationScale * mStartTranslation;
10198f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi            creator.createAnimation(objects[row], delay, mDuration,
1025673353559453ecb57fc767b4e7500dd46e44079Jorim Jaggi                    mAppearing ? translation : -translation,
1035673353559453ecb57fc767b4e7500dd46e44079Jorim Jaggi                    mAppearing, mInterpolator, endRunnable);
10498f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi        }
10598f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi    }
10698f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi
1073018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek    private <T> void startAnimations(AppearAnimationProperties properties, T[][] objects,
10898f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi            final Runnable finishListener, AppearAnimationCreator<T> creator) {
1093018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek        if (properties.maxDelayRowIndex == -1 || properties.maxDelayColIndex == -1) {
1103018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek            finishListener.run();
1113018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek            return;
1123018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek        }
1133018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek        for (int row = 0; row < properties.delays.length; row++) {
1143018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek            long[] columns = properties.delays[row];
1155673353559453ecb57fc767b4e7500dd46e44079Jorim Jaggi            float translationScale = mRowTranslationScaler != null
1165673353559453ecb57fc767b4e7500dd46e44079Jorim Jaggi                    ? mRowTranslationScaler.getRowTranslationScale(row, properties.delays.length)
1175673353559453ecb57fc767b4e7500dd46e44079Jorim Jaggi                    : 1f;
1185673353559453ecb57fc767b4e7500dd46e44079Jorim Jaggi            float translation = translationScale * mStartTranslation;
11915a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi            for (int col = 0; col < columns.length; col++) {
1203018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek                long delay = columns[col];
1213018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek                Runnable endRunnable = null;
1223018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek                if (properties.maxDelayRowIndex == row && properties.maxDelayColIndex == col) {
1233018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek                    endRunnable = finishListener;
12415a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi                }
12598f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi                creator.createAnimation(objects[row][col], delay, mDuration,
126f9c0e8f02f3483d6aa9e762c97a2c02ea50eeb02Selim Cinek                        mAppearing ? translation : -translation,
127f9c0e8f02f3483d6aa9e762c97a2c02ea50eeb02Selim Cinek                        mAppearing, mInterpolator, endRunnable);
12815a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi            }
12915a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi        }
13098f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi    }
1313018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek
13298f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi    private <T> AppearAnimationProperties getDelays(T[] items) {
13398f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi        long maxDelay = -1;
13498f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi        mProperties.maxDelayColIndex = -1;
13598f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi        mProperties.maxDelayRowIndex = -1;
13698f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi        mProperties.delays = new long[items.length][];
13798f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi        for (int row = 0; row < items.length; row++) {
13898f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi            mProperties.delays[row] = new long[1];
13998f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi            long delay = calculateDelay(row, 0);
14098f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi            mProperties.delays[row][0] = delay;
14198f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi            if (items[row] != null && delay > maxDelay) {
14298f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi                maxDelay = delay;
14398f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi                mProperties.maxDelayColIndex = 0;
14498f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi                mProperties.maxDelayRowIndex = row;
14598f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi            }
14698f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi        }
14798f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi        return mProperties;
14815a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi    }
14915a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi
1503018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek    private <T> AppearAnimationProperties getDelays(T[][] items) {
15198f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi        long maxDelay = -1;
1523018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek        mProperties.maxDelayColIndex = -1;
1533018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek        mProperties.maxDelayRowIndex = -1;
1543018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek        mProperties.delays = new long[items.length][];
1553018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek        for (int row = 0; row < items.length; row++) {
1563018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek            T[] columns = items[row];
1573018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek            mProperties.delays[row] = new long[columns.length];
1583018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek            for (int col = 0; col < columns.length; col++) {
1593018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek                long delay = calculateDelay(row, col);
1603018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek                mProperties.delays[row][col] = delay;
1613018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek                if (items[row][col] != null && delay > maxDelay) {
1623018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek                    maxDelay = delay;
1633018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek                    mProperties.maxDelayColIndex = col;
1643018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek                    mProperties.maxDelayRowIndex = row;
1653018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek                }
1663018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek            }
16715a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi        }
1683018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek        return mProperties;
16915a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi    }
17015a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi
171f9c0e8f02f3483d6aa9e762c97a2c02ea50eeb02Selim Cinek    protected long calculateDelay(int row, int col) {
1723018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek        return (long) ((row * 40 + col * (Math.pow(row, 0.4) + 0.4) * 20) * mDelayScale);
17315a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi    }
17415a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi
1753018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek    public Interpolator getInterpolator() {
17698f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi        return mInterpolator;
17715a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi    }
17815a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi
17915a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi    public float getStartTranslation() {
18015a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi        return mStartTranslation;
18115a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi    }
1823018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek
1833018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek    @Override
184613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi    public void createAnimation(final View view, long delay, long duration, float translationY,
185613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi            boolean appearing, Interpolator interpolator, final Runnable endRunnable) {
1863018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek        if (view != null) {
187f9c0e8f02f3483d6aa9e762c97a2c02ea50eeb02Selim Cinek            view.setAlpha(appearing ? 0f : 1.0f);
188f9c0e8f02f3483d6aa9e762c97a2c02ea50eeb02Selim Cinek            view.setTranslationY(appearing ? translationY : 0);
189613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi            Animator alphaAnim;
190613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi            float targetAlpha =  appearing ? 1f : 0f;
191613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi            if (view.isHardwareAccelerated()) {
192613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi                RenderNodeAnimator alphaAnimRt = new RenderNodeAnimator(RenderNodeAnimator.ALPHA,
193613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi                        targetAlpha);
194613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi                alphaAnimRt.setTarget(view);
195613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi                alphaAnim = alphaAnimRt;
196613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi            } else {
197613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi                alphaAnim = ObjectAnimator.ofFloat(view, View.ALPHA, view.getAlpha(), targetAlpha);
198613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi            }
199613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi            alphaAnim.setInterpolator(interpolator);
200613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi            alphaAnim.setDuration(duration);
201613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi            alphaAnim.setStartDelay(delay);
2023018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek            if (view.hasOverlappingRendering()) {
203613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi                view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
204613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi                alphaAnim.addListener(new AnimatorListenerAdapter() {
205613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi                    @Override
206613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi                    public void onAnimationEnd(Animator animation) {
207613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi                        view.setLayerType(View.LAYER_TYPE_NONE, null);
208613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi                    }
209613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi                });
2103018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek            }
2113018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek            if (endRunnable != null) {
212613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi                alphaAnim.addListener(new AnimatorListenerAdapter() {
213613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi                    @Override
214613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi                    public void onAnimationEnd(Animator animation) {
215613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi                        endRunnable.run();
216613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi                    }
217613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi                });
2183018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek            }
219613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi            alphaAnim.start();
220613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi            startTranslationYAnimation(view, delay, duration, appearing ? 0 : translationY,
221613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi                    interpolator);
222613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi        }
223613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi    }
224613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi
225613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi    public static void startTranslationYAnimation(View view, long delay, long duration,
226613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi            float endTranslationY, Interpolator interpolator) {
227613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi        Animator translationAnim;
228613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi        if (view.isHardwareAccelerated()) {
229613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi            RenderNodeAnimator translationAnimRt = new RenderNodeAnimator(
230613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi                    RenderNodeAnimator.TRANSLATION_Y, endTranslationY);
231613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi            translationAnimRt.setTarget(view);
232613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi            translationAnim = translationAnimRt;
233613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi        } else {
234613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi            translationAnim = ObjectAnimator.ofFloat(view, View.TRANSLATION_Y,
235613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi                    view.getTranslationY(), endTranslationY);
2363018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek        }
237613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi        translationAnim.setInterpolator(interpolator);
238613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi        translationAnim.setDuration(duration);
239613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi        translationAnim.setStartDelay(delay);
240613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi        translationAnim.start();
2413018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek    }
2423018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek
2433018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek    public class AppearAnimationProperties {
2443018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek        public long[][] delays;
2453018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek        public int maxDelayRowIndex;
2463018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek        public int maxDelayColIndex;
2473018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek    }
2485673353559453ecb57fc767b4e7500dd46e44079Jorim Jaggi
2495673353559453ecb57fc767b4e7500dd46e44079Jorim Jaggi    public interface RowTranslationScaler {
2505673353559453ecb57fc767b4e7500dd46e44079Jorim Jaggi        float getRowTranslationScale(int row, int numRows);
2515673353559453ecb57fc767b4e7500dd46e44079Jorim Jaggi    }
25215a77f7da856cbed19cb67c75268505a333352f1Jorim Jaggi}
253