Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit be08f261 authored by Tony Mantler's avatar Tony Mantler Committed by android-build-merger
Browse files

Merge "Add hidden slide fraction call to Slide" into nyc-dev

am: ad43160b

* commit 'ad43160b':
  Add hidden slide fraction call to Slide
parents 6e60d159 ad43160b
Loading
Loading
Loading
Loading
+28 −22
Original line number Original line Diff line number Diff line
@@ -47,6 +47,7 @@ public class Slide extends Visibility {
    private static final String PROPNAME_SCREEN_POSITION = "android:slide:screenPosition";
    private static final String PROPNAME_SCREEN_POSITION = "android:slide:screenPosition";
    private CalculateSlide mSlideCalculator = sCalculateBottom;
    private CalculateSlide mSlideCalculator = sCalculateBottom;
    private @GravityFlag int mSlideEdge = Gravity.BOTTOM;
    private @GravityFlag int mSlideEdge = Gravity.BOTTOM;
    private float mSlideFraction = 1;


    /** @hide */
    /** @hide */
    @Retention(RetentionPolicy.SOURCE)
    @Retention(RetentionPolicy.SOURCE)
@@ -56,16 +57,16 @@ public class Slide extends Visibility {
    private interface CalculateSlide {
    private interface CalculateSlide {


        /** Returns the translation value for view when it goes out of the scene */
        /** Returns the translation value for view when it goes out of the scene */
        float getGoneX(ViewGroup sceneRoot, View view);
        float getGoneX(ViewGroup sceneRoot, View view, float fraction);


        /** Returns the translation value for view when it goes out of the scene */
        /** Returns the translation value for view when it goes out of the scene */
        float getGoneY(ViewGroup sceneRoot, View view);
        float getGoneY(ViewGroup sceneRoot, View view, float fraction);
    }
    }


    private static abstract class CalculateSlideHorizontal implements CalculateSlide {
    private static abstract class CalculateSlideHorizontal implements CalculateSlide {


        @Override
        @Override
        public float getGoneY(ViewGroup sceneRoot, View view) {
        public float getGoneY(ViewGroup sceneRoot, View view, float fraction) {
            return view.getTranslationY();
            return view.getTranslationY();
        }
        }
    }
    }
@@ -73,27 +74,27 @@ public class Slide extends Visibility {
    private static abstract class CalculateSlideVertical implements CalculateSlide {
    private static abstract class CalculateSlideVertical implements CalculateSlide {


        @Override
        @Override
        public float getGoneX(ViewGroup sceneRoot, View view) {
        public float getGoneX(ViewGroup sceneRoot, View view, float fraction) {
            return view.getTranslationX();
            return view.getTranslationX();
        }
        }
    }
    }


    private static final CalculateSlide sCalculateLeft = new CalculateSlideHorizontal() {
    private static final CalculateSlide sCalculateLeft = new CalculateSlideHorizontal() {
        @Override
        @Override
        public float getGoneX(ViewGroup sceneRoot, View view) {
        public float getGoneX(ViewGroup sceneRoot, View view, float fraction) {
            return view.getTranslationX() - sceneRoot.getWidth();
            return view.getTranslationX() - sceneRoot.getWidth() * fraction;
        }
        }
    };
    };


    private static final CalculateSlide sCalculateStart = new CalculateSlideHorizontal() {
    private static final CalculateSlide sCalculateStart = new CalculateSlideHorizontal() {
        @Override
        @Override
        public float getGoneX(ViewGroup sceneRoot, View view) {
        public float getGoneX(ViewGroup sceneRoot, View view, float fraction) {
            final boolean isRtl = sceneRoot.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
            final boolean isRtl = sceneRoot.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
            final float x;
            final float x;
            if (isRtl) {
            if (isRtl) {
                x = view.getTranslationX() + sceneRoot.getWidth();
                x = view.getTranslationX() + sceneRoot.getWidth() * fraction;
            } else {
            } else {
                x = view.getTranslationX() - sceneRoot.getWidth();
                x = view.getTranslationX() - sceneRoot.getWidth() * fraction;
            }
            }
            return x;
            return x;
        }
        }
@@ -101,27 +102,27 @@ public class Slide extends Visibility {


    private static final CalculateSlide sCalculateTop = new CalculateSlideVertical() {
    private static final CalculateSlide sCalculateTop = new CalculateSlideVertical() {
        @Override
        @Override
        public float getGoneY(ViewGroup sceneRoot, View view) {
        public float getGoneY(ViewGroup sceneRoot, View view, float fraction) {
            return view.getTranslationY() - sceneRoot.getHeight();
            return view.getTranslationY() - sceneRoot.getHeight() * fraction;
        }
        }
    };
    };


    private static final CalculateSlide sCalculateRight = new CalculateSlideHorizontal() {
    private static final CalculateSlide sCalculateRight = new CalculateSlideHorizontal() {
        @Override
        @Override
        public float getGoneX(ViewGroup sceneRoot, View view) {
        public float getGoneX(ViewGroup sceneRoot, View view, float fraction) {
            return view.getTranslationX() + sceneRoot.getWidth();
            return view.getTranslationX() + sceneRoot.getWidth() * fraction;
        }
        }
    };
    };


    private static final CalculateSlide sCalculateEnd = new CalculateSlideHorizontal() {
    private static final CalculateSlide sCalculateEnd = new CalculateSlideHorizontal() {
        @Override
        @Override
        public float getGoneX(ViewGroup sceneRoot, View view) {
        public float getGoneX(ViewGroup sceneRoot, View view, float fraction) {
            final boolean isRtl = sceneRoot.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
            final boolean isRtl = sceneRoot.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
            final float x;
            final float x;
            if (isRtl) {
            if (isRtl) {
                x = view.getTranslationX() - sceneRoot.getWidth();
                x = view.getTranslationX() - sceneRoot.getWidth() * fraction;
            } else {
            } else {
                x = view.getTranslationX() + sceneRoot.getWidth();
                x = view.getTranslationX() + sceneRoot.getWidth() * fraction;
            }
            }
            return x;
            return x;
        }
        }
@@ -129,8 +130,8 @@ public class Slide extends Visibility {


    private static final CalculateSlide sCalculateBottom = new CalculateSlideVertical() {
    private static final CalculateSlide sCalculateBottom = new CalculateSlideVertical() {
        @Override
        @Override
        public float getGoneY(ViewGroup sceneRoot, View view) {
        public float getGoneY(ViewGroup sceneRoot, View view, float fraction) {
            return view.getTranslationY() + sceneRoot.getHeight();
            return view.getTranslationY() + sceneRoot.getHeight() * fraction;
        }
        }
    };
    };


@@ -237,8 +238,8 @@ public class Slide extends Visibility {
        int[] position = (int[]) endValues.values.get(PROPNAME_SCREEN_POSITION);
        int[] position = (int[]) endValues.values.get(PROPNAME_SCREEN_POSITION);
        float endX = view.getTranslationX();
        float endX = view.getTranslationX();
        float endY = view.getTranslationY();
        float endY = view.getTranslationY();
        float startX = mSlideCalculator.getGoneX(sceneRoot, view);
        float startX = mSlideCalculator.getGoneX(sceneRoot, view, mSlideFraction);
        float startY = mSlideCalculator.getGoneY(sceneRoot, view);
        float startY = mSlideCalculator.getGoneY(sceneRoot, view, mSlideFraction);
        return TranslationAnimationCreator
        return TranslationAnimationCreator
                .createAnimation(view, endValues, position[0], position[1],
                .createAnimation(view, endValues, position[0], position[1],
                        startX, startY, endX, endY, sDecelerate, this);
                        startX, startY, endX, endY, sDecelerate, this);
@@ -253,10 +254,15 @@ public class Slide extends Visibility {
        int[] position = (int[]) startValues.values.get(PROPNAME_SCREEN_POSITION);
        int[] position = (int[]) startValues.values.get(PROPNAME_SCREEN_POSITION);
        float startX = view.getTranslationX();
        float startX = view.getTranslationX();
        float startY = view.getTranslationY();
        float startY = view.getTranslationY();
        float endX = mSlideCalculator.getGoneX(sceneRoot, view);
        float endX = mSlideCalculator.getGoneX(sceneRoot, view, mSlideFraction);
        float endY = mSlideCalculator.getGoneY(sceneRoot, view);
        float endY = mSlideCalculator.getGoneY(sceneRoot, view, mSlideFraction);
        return TranslationAnimationCreator
        return TranslationAnimationCreator
                .createAnimation(view, startValues, position[0], position[1],
                .createAnimation(view, startValues, position[0], position[1],
                        startX, startY, endX, endY, sAccelerate, this);
                        startX, startY, endX, endY, sAccelerate, this);
    }
    }

    /** @hide */
    public void setSlideFraction(float slideFraction) {
        mSlideFraction = slideFraction;
    }
}
}
+174 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License
 */

package android.transition;

import android.animation.AnimatorSetActivity;
import android.app.Activity;
import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.SmallTest;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;

import com.android.frameworks.coretests.R;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;


public class SlideTransitionTest extends ActivityInstrumentationTestCase2<AnimatorSetActivity> {

    Activity mActivity;

    public SlideTransitionTest() {
        super(AnimatorSetActivity.class);
    }

    @Override
    protected void setUp() throws Exception {
        mActivity = getActivity();
    }

    @SmallTest
    public void testShortSlide() throws Throwable {
        final float slideFraction = 0.5f;
        final View square1 = mActivity.findViewById(R.id.square1);
        final View sceneRoot = mActivity.findViewById(R.id.container);
        final SlideTranslationValueRatchet ratchet = new SlideTranslationValueRatchet(square1);
        square1.getViewTreeObserver().addOnPreDrawListener(ratchet);

        final Slide slideOut = new Slide(Gravity.BOTTOM);
        final float finalOffsetOut = sceneRoot.getHeight() * slideFraction;
        slideOut.setSlideFraction(slideFraction);
        TransitionLatch latch = setVisibilityInTransition(slideOut, R.id.square1, View.INVISIBLE);
        assertTrue(latch.startLatch.await(200, TimeUnit.MILLISECONDS));
        assertEquals(0f, square1.getTranslationY(), 0.1f);
        assertEquals(View.VISIBLE, square1.getVisibility());
        Thread.sleep(100);
        assertFalse(square1.getTranslationY() < 0.1
                || square1.getTranslationY() > finalOffsetOut - 0.1);
        assertTrue(latch.endLatch.await(400, TimeUnit.MILLISECONDS));
        // Give this 20% slop in case some frames get dropped.
        assertTrue(finalOffsetOut * 0.8 < ratchet.maxY);
        assertTrue(finalOffsetOut + 0.1 > ratchet.maxY);
        assertEquals(View.INVISIBLE, square1.getVisibility());

        ratchet.reset();
        final Slide slideIn = new Slide(Gravity.BOTTOM);
        final float initialOffsetIn = sceneRoot.getHeight() * slideFraction;
        slideIn.setSlideFraction(slideFraction);
        latch = setVisibilityInTransition(slideIn, R.id.square1, View.VISIBLE);
        assertTrue(latch.startLatch.await(200, TimeUnit.MILLISECONDS));
        assertEquals(initialOffsetIn, square1.getTranslationY(), 0.1f);
        assertEquals(View.VISIBLE, square1.getVisibility());
        Thread.sleep(100);
        assertFalse(square1.getTranslationY() < 0.1
                || square1.getTranslationY() > initialOffsetIn - 0.1);
        assertTrue(latch.endLatch.await(400, TimeUnit.MILLISECONDS));
        assertEquals(0f, ratchet.minY, 0.1);
        assertEquals(0f, square1.getTranslationY(), 0.1);
        assertEquals(View.VISIBLE, square1.getVisibility());

        square1.getViewTreeObserver().removeOnPreDrawListener(ratchet);
    }

    public TransitionLatch setVisibilityInTransition(final Transition transition, int viewId,
            final int visibility) throws Throwable {
        final ViewGroup sceneRoot = (ViewGroup) mActivity.findViewById(R.id.container);
        final View view = sceneRoot.findViewById(viewId);
        TransitionLatch latch = new TransitionLatch();
        transition.addListener(latch);
        runTestOnUiThread(new Runnable() {
            @Override
            public void run() {
                TransitionManager.beginDelayedTransition(sceneRoot, transition);
                view.setVisibility(visibility);
            }
        });
        return latch;
    }

    public static class TransitionLatch implements Transition.TransitionListener {
        public CountDownLatch startLatch = new CountDownLatch(1);
        public CountDownLatch endLatch = new CountDownLatch(1);
        public CountDownLatch cancelLatch = new CountDownLatch(1);
        public CountDownLatch pauseLatch = new CountDownLatch(1);
        public CountDownLatch resumeLatch = new CountDownLatch(1);

        @Override
        public void onTransitionStart(Transition transition) {
            startLatch.countDown();
        }

        @Override
        public void onTransitionEnd(Transition transition) {
            endLatch.countDown();
            transition.removeListener(this);
        }

        @Override
        public void onTransitionCancel(Transition transition) {
            cancelLatch.countDown();
        }

        @Override
        public void onTransitionPause(Transition transition) {
            pauseLatch.countDown();
        }

        @Override
        public void onTransitionResume(Transition transition) {
            resumeLatch.countDown();
        }
    }

    private static class SlideTranslationValueRatchet
            implements ViewTreeObserver.OnPreDrawListener {

        private final View mView;
        private boolean mInitialized;
        public float minX = Float.NaN;
        public float minY = Float.NaN;
        public float maxX = Float.NaN;
        public float maxY = Float.NaN;

        public SlideTranslationValueRatchet(View view) {
            mView = view;
        }

        public void reset() {
            minX = minY = maxX = maxY = Float.NaN;
            mInitialized = false;
        }

        @Override
        public boolean onPreDraw() {
            if (!mInitialized) {
                minX = maxX = mView.getTranslationX();
                minY = maxY = mView.getTranslationY();
                mInitialized = true;
            } else {
                minX = Math.min(minX, mView.getTranslationX());
                minY = Math.min(minY, mView.getTranslationY());
                maxX = Math.max(maxX, mView.getTranslationX());
                maxY = Math.max(maxY, mView.getTranslationY());
            }
            return true;
        }
    }
}