16d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu/*
26d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu * Copyright (C) 2015 The Android Open Source Project
36d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu *
46d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu * Licensed under the Apache License, Version 2.0 (the "License");
56d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu * you may not use this file except in compliance with the License.
66d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu * You may obtain a copy of the License at
76d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu *
86d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu *      http://www.apache.org/licenses/LICENSE-2.0
96d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu *
106d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu * Unless required by applicable law or agreed to in writing, software
116d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu * distributed under the License is distributed on an "AS IS" BASIS,
126d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu * See the License for the specific language governing permissions and
146d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu * limitations under the License.
156d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu */
166d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gupackage android.support.v17.leanback.transition;
176d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu
188e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikasimport static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
198e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikas
206d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Guimport android.animation.Animator;
216d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Guimport android.animation.AnimatorSet;
226d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Guimport android.animation.TimeInterpolator;
23834c40f1fdb97d2735c5131975eda4acdee4612esusnataimport android.content.Context;
24834c40f1fdb97d2735c5131975eda4acdee4612esusnataimport android.content.res.TypedArray;
25fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Guimport android.graphics.Rect;
268f886fe8c7e23fe6ccb8734167c960c2ed3429c3Alan Viveretteimport android.support.annotation.RequiresApi;
27c39d9c75590eca86a5e7e32a8824ba04a0d42e9bAlan Viveretteimport android.support.annotation.RestrictTo;
28834c40f1fdb97d2735c5131975eda4acdee4612esusnataimport android.support.v17.leanback.R;
2962ae6346f88bfd8e1655e7cf7181b845e68366f4Tony Mantlerimport android.transition.Fade;
306d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Guimport android.transition.Transition;
316d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Guimport android.transition.TransitionValues;
326d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Guimport android.transition.Visibility;
33834c40f1fdb97d2735c5131975eda4acdee4612esusnataimport android.util.AttributeSet;
346d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Guimport android.view.Gravity;
356d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Guimport android.view.View;
366d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Guimport android.view.ViewGroup;
376d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Guimport android.view.animation.DecelerateInterpolator;
386d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu
396d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu/**
406d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu * Execute horizontal slide of 1/4 width and fade (to workaround bug 23718734)
416d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu * @hide
426d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu */
438f886fe8c7e23fe6ccb8734167c960c2ed3429c3Alan Viverette@RequiresApi(21)
448e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikas@RestrictTo(LIBRARY_GROUP)
456d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gupublic class FadeAndShortSlide extends Visibility {
466d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu
476d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu    private static final TimeInterpolator sDecelerate = new DecelerateInterpolator();
486d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu    // private static final TimeInterpolator sAccelerate = new AccelerateInterpolator();
496d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu    private static final String PROPNAME_SCREEN_POSITION =
506d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu            "android:fadeAndShortSlideTransition:screenPosition";
516d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu
52fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu    private CalculateSlide mSlideCalculator;
5362ae6346f88bfd8e1655e7cf7181b845e68366f4Tony Mantler    private Visibility mFade = new Fade();
54fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu    private float mDistance = -1;
556d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu
56fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu    private static abstract class CalculateSlide {
576d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu
5899ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas        CalculateSlide() {
5999ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas        }
6099ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas
61fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu        /** Returns the translation X value for view when it goes out of the scene */
62fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu        float getGoneX(FadeAndShortSlide t, ViewGroup sceneRoot, View view, int[] position) {
63fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu            return view.getTranslationX();
64fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu        }
65fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu
66fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu        /** Returns the translation Y value for view when it goes out of the scene */
67fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu        float getGoneY(FadeAndShortSlide t, ViewGroup sceneRoot, View view, int[] position) {
68fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu            return view.getTranslationY();
69fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu        }
70fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu    }
71fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu
72fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu    float getHorizontalDistance(ViewGroup sceneRoot) {
73fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu        return mDistance >= 0 ? mDistance : (sceneRoot.getWidth() / 4);
746d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu    }
756d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu
76fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu    float getVerticalDistance(ViewGroup sceneRoot) {
77fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu        return mDistance >= 0 ? mDistance : (sceneRoot.getHeight() / 4);
78fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu    }
79fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu
80fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu    final static CalculateSlide sCalculateStart = new CalculateSlide() {
816d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu        @Override
82fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu        public float getGoneX(FadeAndShortSlide t, ViewGroup sceneRoot, View view, int[] position) {
836d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu            final boolean isRtl = sceneRoot.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
846d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu            final float x;
856d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu            if (isRtl) {
86fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu                x = view.getTranslationX() + t.getHorizontalDistance(sceneRoot);
876d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu            } else {
88fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu                x = view.getTranslationX() - t.getHorizontalDistance(sceneRoot);
896d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu            }
906d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu            return x;
916d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu        }
926d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu    };
936d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu
94fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu    final static CalculateSlide sCalculateEnd = new CalculateSlide() {
956d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu        @Override
96fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu        public float getGoneX(FadeAndShortSlide t, ViewGroup sceneRoot, View view, int[] position) {
976d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu            final boolean isRtl = sceneRoot.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
986d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu            final float x;
996d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu            if (isRtl) {
100fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu                x = view.getTranslationX() - t.getHorizontalDistance(sceneRoot);
1016d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu            } else {
102fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu                x = view.getTranslationX() + t.getHorizontalDistance(sceneRoot);
1036d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu            }
1046d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu            return x;
1056d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu        }
1066d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu    };
1076d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu
108fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu    final static CalculateSlide sCalculateStartEnd = new CalculateSlide() {
1092be7e6dbeec0a7c9fe1453cf6fd4f75a8c1c69f6Dake Gu        @Override
110fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu        public float getGoneX(FadeAndShortSlide t, ViewGroup sceneRoot, View view, int[] position) {
1112be7e6dbeec0a7c9fe1453cf6fd4f75a8c1c69f6Dake Gu            final int viewCenter = position[0] + view.getWidth() / 2;
1122be7e6dbeec0a7c9fe1453cf6fd4f75a8c1c69f6Dake Gu            sceneRoot.getLocationOnScreen(position);
113fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu            Rect center = t.getEpicenter();
114fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu            final int sceneRootCenter = center == null ? (position[0] + sceneRoot.getWidth() / 2)
115fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu                    : center.centerX();
1162be7e6dbeec0a7c9fe1453cf6fd4f75a8c1c69f6Dake Gu            if (viewCenter < sceneRootCenter) {
117fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu                return view.getTranslationX() - t.getHorizontalDistance(sceneRoot);
1182be7e6dbeec0a7c9fe1453cf6fd4f75a8c1c69f6Dake Gu            } else {
119fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu                return view.getTranslationX() + t.getHorizontalDistance(sceneRoot);
120fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu            }
121fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu        }
122fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu    };
123fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu
124fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu    final static CalculateSlide sCalculateBottom = new CalculateSlide() {
125fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu        @Override
126fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu        public float getGoneY(FadeAndShortSlide t, ViewGroup sceneRoot, View view, int[] position) {
127fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu            return view.getTranslationY() + t.getVerticalDistance(sceneRoot);
128fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu        }
129fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu    };
130fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu
131fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu    final static CalculateSlide sCalculateTop = new CalculateSlide() {
132fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu        @Override
133fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu        public float getGoneY(FadeAndShortSlide t, ViewGroup sceneRoot, View view, int[] position) {
134fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu            return view.getTranslationY() - t.getVerticalDistance(sceneRoot);
135fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu        }
136fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu    };
137fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu
138fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu    final CalculateSlide sCalculateTopBottom = new CalculateSlide() {
139fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu        @Override
140fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu        public float getGoneY(FadeAndShortSlide t, ViewGroup sceneRoot, View view, int[] position) {
141fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu            final int viewCenter = position[1] + view.getHeight() / 2;
142fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu            sceneRoot.getLocationOnScreen(position);
143fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu            Rect center = getEpicenter();
144fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu            final int sceneRootCenter = center == null ? (position[1] + sceneRoot.getHeight() / 2)
145fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu                    : center.centerY();
146fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu            if (viewCenter < sceneRootCenter) {
147fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu                return view.getTranslationY() - t.getVerticalDistance(sceneRoot);
148fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu            } else {
149fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu                return view.getTranslationY() + t.getVerticalDistance(sceneRoot);
1502be7e6dbeec0a7c9fe1453cf6fd4f75a8c1c69f6Dake Gu            }
1512be7e6dbeec0a7c9fe1453cf6fd4f75a8c1c69f6Dake Gu        }
1522be7e6dbeec0a7c9fe1453cf6fd4f75a8c1c69f6Dake Gu    };
1532be7e6dbeec0a7c9fe1453cf6fd4f75a8c1c69f6Dake Gu
1546d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu    public FadeAndShortSlide() {
1556d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu        this(Gravity.START);
1566d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu    }
1576d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu
1586d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu    public FadeAndShortSlide(int slideEdge) {
1596d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu        setSlideEdge(slideEdge);
1606d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu    }
1616d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu
162834c40f1fdb97d2735c5131975eda4acdee4612esusnata    public FadeAndShortSlide(Context context, AttributeSet attrs) {
163834c40f1fdb97d2735c5131975eda4acdee4612esusnata        super(context, attrs);
164834c40f1fdb97d2735c5131975eda4acdee4612esusnata        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.lbSlide);
165834c40f1fdb97d2735c5131975eda4acdee4612esusnata        int edge = a.getInt(R.styleable.lbSlide_lb_slideEdge, Gravity.START);
166834c40f1fdb97d2735c5131975eda4acdee4612esusnata        setSlideEdge(edge);
167834c40f1fdb97d2735c5131975eda4acdee4612esusnata        a.recycle();
168834c40f1fdb97d2735c5131975eda4acdee4612esusnata    }
169834c40f1fdb97d2735c5131975eda4acdee4612esusnata
1706d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu    @Override
1716d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu    public void setEpicenterCallback(EpicenterCallback epicenterCallback) {
17262ae6346f88bfd8e1655e7cf7181b845e68366f4Tony Mantler        mFade.setEpicenterCallback(epicenterCallback);
1736d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu        super.setEpicenterCallback(epicenterCallback);
1746d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu    }
1756d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu
1766d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu    private void captureValues(TransitionValues transitionValues) {
1776d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu        View view = transitionValues.view;
1786d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu        int[] position = new int[2];
1796d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu        view.getLocationOnScreen(position);
1802be7e6dbeec0a7c9fe1453cf6fd4f75a8c1c69f6Dake Gu        transitionValues.values.put(PROPNAME_SCREEN_POSITION, position);
1816d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu    }
1826d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu
1836d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu    @Override
1846d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu    public void captureStartValues(TransitionValues transitionValues) {
18562ae6346f88bfd8e1655e7cf7181b845e68366f4Tony Mantler        mFade.captureStartValues(transitionValues);
1866d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu        super.captureStartValues(transitionValues);
1876d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu        captureValues(transitionValues);
1886d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu    }
1896d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu
1906d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu    @Override
1916d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu    public void captureEndValues(TransitionValues transitionValues) {
19262ae6346f88bfd8e1655e7cf7181b845e68366f4Tony Mantler        mFade.captureEndValues(transitionValues);
1936d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu        super.captureEndValues(transitionValues);
1946d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu        captureValues(transitionValues);
1956d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu    }
1966d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu
1976d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu    public void setSlideEdge(int slideEdge) {
1986d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu        switch (slideEdge) {
1996d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu            case Gravity.START:
2006d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu                mSlideCalculator = sCalculateStart;
2016d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu                break;
2026d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu            case Gravity.END:
2036d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu                mSlideCalculator = sCalculateEnd;
2046d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu                break;
2052be7e6dbeec0a7c9fe1453cf6fd4f75a8c1c69f6Dake Gu            case Gravity.START | Gravity.END:
206fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu                mSlideCalculator = sCalculateStartEnd;
207fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu                break;
208fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu            case Gravity.TOP:
209fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu                mSlideCalculator = sCalculateTop;
210fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu                break;
211fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu            case Gravity.BOTTOM:
212fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu                mSlideCalculator = sCalculateBottom;
213fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu                break;
214fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu            case Gravity.TOP | Gravity.BOTTOM:
215fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu                mSlideCalculator = sCalculateTopBottom;
2162be7e6dbeec0a7c9fe1453cf6fd4f75a8c1c69f6Dake Gu                break;
2176d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu            default:
2186d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu                throw new IllegalArgumentException("Invalid slide direction");
2196d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu        }
2206d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu    }
2216d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu
2226d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu    @Override
2236d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu    public Animator onAppear(ViewGroup sceneRoot, View view, TransitionValues startValues,
2246d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu            TransitionValues endValues) {
2256d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu        if (endValues == null) {
2266d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu            return null;
2276d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu        }
228fd23a2faf77c66a405a2b2974f719041feda9177Dake Gu        if (sceneRoot == view) {
229fd23a2faf77c66a405a2b2974f719041feda9177Dake Gu            // workaround b/25375640, avoid run animation on sceneRoot
230fd23a2faf77c66a405a2b2974f719041feda9177Dake Gu            return null;
231fd23a2faf77c66a405a2b2974f719041feda9177Dake Gu        }
2322be7e6dbeec0a7c9fe1453cf6fd4f75a8c1c69f6Dake Gu        int[] position = (int[]) endValues.values.get(PROPNAME_SCREEN_POSITION);
2332be7e6dbeec0a7c9fe1453cf6fd4f75a8c1c69f6Dake Gu        int left = position[0];
234fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu        int top = position[1];
2356d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu        float endX = view.getTranslationX();
236fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu        float startX = mSlideCalculator.getGoneX(this, sceneRoot, view, position);
237fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu        float endY = view.getTranslationY();
238fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu        float startY = mSlideCalculator.getGoneY(this, sceneRoot, view, position);
2396d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu        final Animator slideAnimator = TranslationAnimationCreator.createAnimation(view, endValues,
240fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu                left, top, startX, startY, endX, endY, sDecelerate, this);
24162ae6346f88bfd8e1655e7cf7181b845e68366f4Tony Mantler        final Animator fadeAnimator = mFade.onAppear(sceneRoot, view, startValues, endValues);
242fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu        if (slideAnimator == null) {
243fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu            return fadeAnimator;
244fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu        } else if (fadeAnimator == null) {
245fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu            return slideAnimator;
246fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu        }
2476d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu        final AnimatorSet set = new AnimatorSet();
248fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu        set.play(slideAnimator).with(fadeAnimator);
2496d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu
2506d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu        return set;
2516d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu    }
2526d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu
2536d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu    @Override
2546d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu    public Animator onDisappear(ViewGroup sceneRoot, View view, TransitionValues startValues,
2556d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu            TransitionValues endValues) {
2566d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu        if (startValues == null) {
2576d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu            return null;
2586d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu        }
259fd23a2faf77c66a405a2b2974f719041feda9177Dake Gu        if (sceneRoot == view) {
260fd23a2faf77c66a405a2b2974f719041feda9177Dake Gu            // workaround b/25375640, avoid run animation on sceneRoot
261fd23a2faf77c66a405a2b2974f719041feda9177Dake Gu            return null;
262fd23a2faf77c66a405a2b2974f719041feda9177Dake Gu        }
2632be7e6dbeec0a7c9fe1453cf6fd4f75a8c1c69f6Dake Gu        int[] position = (int[]) startValues.values.get(PROPNAME_SCREEN_POSITION);
2642be7e6dbeec0a7c9fe1453cf6fd4f75a8c1c69f6Dake Gu        int left = position[0];
265fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu        int top = position[1];
2666d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu        float startX = view.getTranslationX();
267fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu        float endX = mSlideCalculator.getGoneX(this, sceneRoot, view, position);
268fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu        float startY = view.getTranslationY();
269fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu        float endY = mSlideCalculator.getGoneY(this, sceneRoot, view, position);
2706d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu        final Animator slideAnimator = TranslationAnimationCreator.createAnimation(view,
271fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu                startValues, left, top, startX, startY, endX, endY, sDecelerate /* sAccelerate */,
272fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu                this);
27362ae6346f88bfd8e1655e7cf7181b845e68366f4Tony Mantler        final Animator fadeAnimator = mFade.onDisappear(sceneRoot, view, startValues, endValues);
274fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu        if (slideAnimator == null) {
275fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu            return fadeAnimator;
276fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu        } else if (fadeAnimator == null) {
277fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu            return slideAnimator;
278fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu        }
2796d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu        final AnimatorSet set = new AnimatorSet();
280fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu        set.play(slideAnimator).with(fadeAnimator);
2816d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu
2826d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu        return set;
2836d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu    }
2846d760296101d0dd1f3df8a696e0bf82ffaee2a49Dake Gu
28562ae6346f88bfd8e1655e7cf7181b845e68366f4Tony Mantler    @Override
28662ae6346f88bfd8e1655e7cf7181b845e68366f4Tony Mantler    public Transition addListener(TransitionListener listener) {
28762ae6346f88bfd8e1655e7cf7181b845e68366f4Tony Mantler        mFade.addListener(listener);
28862ae6346f88bfd8e1655e7cf7181b845e68366f4Tony Mantler        return super.addListener(listener);
28962ae6346f88bfd8e1655e7cf7181b845e68366f4Tony Mantler    }
29062ae6346f88bfd8e1655e7cf7181b845e68366f4Tony Mantler
29162ae6346f88bfd8e1655e7cf7181b845e68366f4Tony Mantler    @Override
29262ae6346f88bfd8e1655e7cf7181b845e68366f4Tony Mantler    public Transition removeListener(TransitionListener listener) {
29362ae6346f88bfd8e1655e7cf7181b845e68366f4Tony Mantler        mFade.removeListener(listener);
29462ae6346f88bfd8e1655e7cf7181b845e68366f4Tony Mantler        return super.removeListener(listener);
29562ae6346f88bfd8e1655e7cf7181b845e68366f4Tony Mantler    }
29662ae6346f88bfd8e1655e7cf7181b845e68366f4Tony Mantler
297fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu    /**
298fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu     * Returns distance to slide.  When negative value is returned, it will use 1/4 of
299fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu     * sceneRoot dimension.
300fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu     */
301fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu    public float getDistance() {
302fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu        return mDistance;
303fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu    }
304fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu
305fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu    /**
306fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu     * Set distance to slide, default value is -1.  when negative value is set, it will use 1/4 of
307fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu     * sceneRoot dimension.
308fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu     * @param distance Pixels to slide.
309fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu     */
310fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu    public void setDistance(float distance) {
311fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu        mDistance = distance;
312fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu    }
313fcca591288721bd6a2e11fd3f78da190ddcd62e9Dake Gu
31462ae6346f88bfd8e1655e7cf7181b845e68366f4Tony Mantler    @Override
31562ae6346f88bfd8e1655e7cf7181b845e68366f4Tony Mantler    public Transition clone() {
31662ae6346f88bfd8e1655e7cf7181b845e68366f4Tony Mantler        FadeAndShortSlide clone = null;
31762ae6346f88bfd8e1655e7cf7181b845e68366f4Tony Mantler        clone = (FadeAndShortSlide) super.clone();
31862ae6346f88bfd8e1655e7cf7181b845e68366f4Tony Mantler        clone.mFade = (Visibility) mFade.clone();
31962ae6346f88bfd8e1655e7cf7181b845e68366f4Tony Mantler        return clone;
32084684fa1e00bd2202b794a8b5fac136c0272d4d3susnata    }
32184684fa1e00bd2202b794a8b5fac136c0272d4d3susnata}
322