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

Commit 997af168 authored by Justin Klaassen's avatar Justin Klaassen
Browse files

Use platform PathInterpolator on API 21+

Change-Id: Id70e2491107de66903668a7a716f16e41291cab3
parent f7328d9b
Loading
Loading
Loading
Loading
+101 −80
Original line number Diff line number Diff line
@@ -16,42 +16,120 @@

package com.android.deskclock;

import android.animation.TimeInterpolator;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.os.Build;
import android.view.animation.Interpolator;
import android.view.animation.PathInterpolator;

/**
 * An interpolator that can traverse a Path that extends from <code>Point</code>
 * {@code (0, 0)} to {@code (1, 1)}. The x coordinate along the {@link Path}
 * is the input value and the output is the y coordinate of the line at that point.
 * This means that the Path must conform to a function {@code y = f(x)}.
 * Helper for creating path-based {@link Interpolator} instances. On API 21 or newer, the
 * platform {@link PathInterpolator} will be used and on older platforms a compatible alternative
 * implementation will be used.
 */
public class PathInterpolatorCompat {

    private PathInterpolatorCompat() {
        // prevent instantiation
    }

    /**
     * Create an {@link Interpolator} for an arbitrary {@link Path}. The {@link Path}
     * must begin at {@code (0, 0)} and end at {@code (1, 1)}. The x-coordinate along the
     * {@link Path} is the input value and the output is the y coordinate of the line at that
     * point. This means that the Path must conform to a function {@code y = f(x)}.
     * <p/>
     * The {@link Path} must not have gaps in the x direction and must not
     * loop back on itself such that there can be two points sharing the same x coordinate.
     *
     * @param path the {@link Path} to use to make the line representing the {@link Interpolator}
     * @return the {@link Interpolator} representing the {@link Path}
     */
public final class PathInterpolatorCompat implements TimeInterpolator {
    public static Interpolator create(Path path) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            return new PathInterpolator(path);
        }
        return new PathInterpolatorCompatIMPL(path);
    }

    /**
     * Governs the accuracy of the approximation of the {@link Path}.
     * Create an {@link Interpolator} for a quadratic Bezier curve. The end points
     * {@code (0, 0)} and {@code (1, 1)} are assumed.
     *
     * @param controlX the x coordinate of the quadratic Bezier control point
     * @param controlY the y coordinate of the quadratic Bezier control point
     * @return the {@link Interpolator} representing the quadratic Bezier curve
     */
    private static final float PRECISION = 0.002f;
    public static Interpolator create(float controlX, float controlY) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            return new PathInterpolator(controlX, controlY);
        }
        return new PathInterpolatorCompatIMPL(createQuad(controlX, controlY));
    }

    /**
     * The x-coordinates in the {@link Path}.
     * Create an {@link Interpolator} for a cubic Bezier curve.  The end points
     * {@code (0, 0)} and {@code (1, 1)} are assumed.
     *
     * @param controlX1 the x coordinate of the first control point of the cubic Bezier
     * @param controlY1 the y coordinate of the first control point of the cubic Bezier
     * @param controlX2 the x coordinate of the second control point of the cubic Bezier
     * @param controlY2 the y coordinate of the second control point of the cubic Bezier
     * @return the {@link Interpolator} representing the cubic Bezier curve
     */
    private final float[] mX;
    public static Interpolator create(float controlX1, float controlY1,
            float controlX2, float controlY2) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            return new PathInterpolator(controlX1, controlY1, controlX2, controlY2);
        }
        return new PathInterpolatorCompatIMPL(
                createCubic(controlX1, controlY1, controlX2, controlY2));
    }

    /**
     * The y-coordinates in the {@link Path}.
     * Create a {@link Path} representing a quadratic Bezier curve. The end points
     * {@code (0, 0)} and {@code (1, 1)} are assumed.
     *
     * @param controlX the x coordinate of the quadratic Bezier control point
     * @param controlY the y coordinate of the quadratic Bezier control point
     * @return the {@link Path} representing the quadratic Bezier curve
     */
    private final float[] mY;
    private static Path createQuad(float controlX, float controlY) {
        final Path path = new Path();
        path.moveTo(0.0f, 0.0f);
        path.quadTo(controlX, controlY, 1.0f, 1.0f);
        return path;
    }

    /**
     * Create an interpolator for an arbitrary {@link Path}. The {@link Path}
     * must begin at {@code (0, 0)} and end at {@code (1, 1)}.
     * Create a {@link Path} representing a cubic Bezier curve. The end points
     * {@code (0, 0)} and {@code (1, 1)} are assumed.
     *
     * @param path the {@link Path} to use to make the line representing the interpolator
     * @param controlX1 the x coordinate of the first control point of the cubic Bezier
     * @param controlY1 the y coordinate of the first control point of the cubic Bezier
     * @param controlX2 the x coordinate of the second control point of the cubic Bezier
     * @param controlY2 the y coordinate of the second control point of the cubic Bezier
     * @return the {@link Path} representing the quadratic Bezier curve
     */
    public PathInterpolatorCompat(Path path) {
    private static Path createCubic(float controlX1, float controlY1,
            float controlX2, float controlY2) {
        final Path path = new Path();
        path.moveTo(0.0f, 0.0f);
        path.cubicTo(controlX1, controlY1, controlX2, controlY2, 1.0f, 1.0f);
        return path;
    }

    private static class PathInterpolatorCompatIMPL implements Interpolator {

        /**
         * Governs the accuracy of the approximation of the {@link Path}.
         */
        private static final float PRECISION = 0.002f;

        private final float[] mX;
        private final float[] mY;

        public PathInterpolatorCompatIMPL(Path path) {
            final PathMeasure pathMeasure = new PathMeasure(path, false /* forceClosed */);

            final float pathLength = pathMeasure.getLength();
@@ -70,31 +148,6 @@ public final class PathInterpolatorCompat implements TimeInterpolator {
            }
        }

    /**
     * Create an interpolator for a quadratic Bezier curve. The end points
     * {@code (0, 0)} and {@code (1, 1)} are assumed.
     *
     * @param controlX the x coordinate of the quadratic Bezier control point
     * @param controlY the y coordinate of the quadratic Bezier control point
     */
    public PathInterpolatorCompat(float controlX, float controlY) {
        this(createQuad(controlX, controlY));
    }

    /**
     * Create an interpolator for a cubic Bezier curve.  The end points
     * {@code (0, 0)} and {@code (1, 1)} are assumed.
     *
     * @param controlX1 the x coordinate of the first control point of the cubic Bezier
     * @param controlY1 the y coordinate of the first control point of the cubic Bezier
     * @param controlX2 the x coordinate of the second control point of the cubic Bezier
     * @param controlY2 the y coordinate of the second control point of the cubic Bezier
     */
    public PathInterpolatorCompat(float controlX1, float controlY1,
            float controlX2, float controlY2) {
        this(createCubic(controlX1, controlY1, controlX2, controlY2));
    }

        @Override
        public float getInterpolation(float t) {
            if (t <= 0.0f) {
@@ -128,37 +181,5 @@ public final class PathInterpolatorCompat implements TimeInterpolator {

            return startY + (fraction * (endY - startY));
        }

    /**
     * Create a {@link Path} representing a quadratic Bezier curve. The end points
     * {@code (0, 0)} and {@code (1, 1)} are assumed.
     *
     * @param controlX the x coordinate of the quadratic Bezier control point
     * @param controlY the y coordinate of the quadratic Bezier control point
     * @return the {@link Path} representing the quadratic Bezier curve
     */
    private static Path createQuad(float controlX, float controlY) {
        final Path path = new Path();
        path.moveTo(0.0f, 0.0f);
        path.quadTo(controlX, controlY, 1.0f, 1.0f);
        return path;
    }

    /**
     * Create a {@link Path} representing a cubic Bezier curve. The end points
     * {@code (0, 0)} and {@code (1, 1)} are assumed.
     *
     * @param controlX1 the x coordinate of the first control point of the cubic Bezier
     * @param controlY1 the y coordinate of the first control point of the cubic Bezier
     * @param controlX2 the x coordinate of the second control point of the cubic Bezier
     * @param controlY2 the y coordinate of the second control point of the cubic Bezier
     * @return the {@link Path} representing the quadratic Bezier curve
     */
    private static Path createCubic(float controlX1, float controlY1,
            float controlX2, float controlY2) {
        final Path path = new Path();
        path.moveTo(0.0f, 0.0f);
        path.cubicTo(controlX1, controlY1, controlX2, controlY2, 1.0f, 1.0f);
        return path;
    }
}
+2 −2
Original line number Diff line number Diff line
@@ -73,9 +73,9 @@ public class AlarmActivity extends AppCompatActivity
    private static final String LOGTAG = AlarmActivity.class.getSimpleName();

    private static final TimeInterpolator PULSE_INTERPOLATOR =
            new PathInterpolatorCompat(0.4f, 0.0f, 0.2f, 1.0f);
            PathInterpolatorCompat.create(0.4f, 0.0f, 0.2f, 1.0f);
    private static final TimeInterpolator REVEAL_INTERPOLATOR =
            new PathInterpolatorCompat(0.0f, 0.0f, 0.2f, 1.0f);
            PathInterpolatorCompat.create(0.0f, 0.0f, 0.2f, 1.0f);

    private static final int PULSE_DURATION_MILLIS = 1000;
    private static final int ALARM_BOUNCE_DURATION_MILLIS = 500;
+1 −1
Original line number Diff line number Diff line
@@ -575,7 +575,7 @@ public class TimerFullScreenFragment extends DeskClockFragment

        final Animator revealAnimator = ObjectAnimator.ofFloat(
                revealView, CircleView.RADIUS, startRadius, endRadius);
        revealAnimator.setInterpolator(new PathInterpolatorCompat(0.0f, 0.0f, 0.2f, 1.0f));
        revealAnimator.setInterpolator(PathInterpolatorCompat.create(0.0f, 0.0f, 0.2f, 1.0f));

        final ValueAnimator fadeAnimator = ObjectAnimator.ofFloat(revealView, View.ALPHA, 0.0f);
        fadeAnimator.addListener(new AnimatorListenerAdapter() {