FileDocCategorySizeDatePackage
PathInterpolator.javaAPI DocAndroid 5.1 API9043Thu Mar 12 22:22:10 GMT 2015android.view.animation

PathInterpolator

public class PathInterpolator extends BaseInterpolator
An interpolator that can traverse a Path that extends from Point (0, 0) to (1, 1). The x coordinate along the 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 y = f(x).

The 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. It is alright to have a disjoint line in the vertical direction:

Path path = new Path();
path.lineTo(0.25f, 0.25f);
path.moveTo(0.25f, 0.5f);
path.lineTo(1f, 1f);

Fields Summary
private static final float
PRECISION
private float[]
mX
private float[]
mY
Constructors Summary
public PathInterpolator(android.graphics.Path path)
Create an interpolator for an arbitrary Path. The Path must begin at (0, 0) and end at (1, 1).

param
path The Path to use to make the line representing the interpolator.

 // y coordinates in the line

                                         
       
        initPath(path);
    
public PathInterpolator(float controlX, float controlY)
Create an interpolator for a quadratic Bezier curve. The end points (0, 0) and (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.

        initQuad(controlX, controlY);
    
public PathInterpolator(float controlX1, float controlY1, float controlX2, float controlY2)
Create an interpolator for a cubic Bezier curve. The end points (0, 0) and (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.

        initCubic(controlX1, controlY1, controlX2, controlY2);
    
public PathInterpolator(android.content.Context context, android.util.AttributeSet attrs)

        this(context.getResources(), context.getTheme(), attrs);
    
public PathInterpolator(android.content.res.Resources res, android.content.res.Resources.Theme theme, android.util.AttributeSet attrs)

hide

        TypedArray a;
        if (theme != null) {
            a = theme.obtainStyledAttributes(attrs, R.styleable.PathInterpolator, 0, 0);
        } else {
            a = res.obtainAttributes(attrs, R.styleable.PathInterpolator);
        }
        parseInterpolatorFromTypeArray(a);
        setChangingConfiguration(a.getChangingConfigurations());
        a.recycle();
    
Methods Summary
public floatgetInterpolation(float t)
Using the line in the Path in this interpolator that can be described as y = f(x), finds the y coordinate of the line given t as the x coordinate. Values less than 0 will always return 0 and values greater than 1 will always return 1.

param
t Treated as the x coordinate along the line.
return
The y coordinate of the Path along the line where x = t.
see
Interpolator#getInterpolation(float)

        if (t <= 0) {
            return 0;
        } else if (t >= 1) {
            return 1;
        }
        // Do a binary search for the correct x to interpolate between.
        int startIndex = 0;
        int endIndex = mX.length - 1;

        while (endIndex - startIndex > 1) {
            int midIndex = (startIndex + endIndex) / 2;
            if (t < mX[midIndex]) {
                endIndex = midIndex;
            } else {
                startIndex = midIndex;
            }
        }

        float xRange = mX[endIndex] - mX[startIndex];
        if (xRange == 0) {
            return mY[startIndex];
        }

        float tInRange = t - mX[startIndex];
        float fraction = tInRange / xRange;

        float startY = mY[startIndex];
        float endY = mY[endIndex];
        return startY + (fraction * (endY - startY));
    
private voidinitCubic(float x1, float y1, float x2, float y2)

        Path path = new Path();
        path.moveTo(0, 0);
        path.cubicTo(x1, y1, x2, y2, 1f, 1f);
        initPath(path);
    
private voidinitPath(android.graphics.Path path)

        float[] pointComponents = path.approximate(PRECISION);

        int numPoints = pointComponents.length / 3;
        if (pointComponents[1] != 0 || pointComponents[2] != 0
                || pointComponents[pointComponents.length - 2] != 1
                || pointComponents[pointComponents.length - 1] != 1) {
            throw new IllegalArgumentException("The Path must start at (0,0) and end at (1,1)");
        }

        mX = new float[numPoints];
        mY = new float[numPoints];
        float prevX = 0;
        float prevFraction = 0;
        int componentIndex = 0;
        for (int i = 0; i < numPoints; i++) {
            float fraction = pointComponents[componentIndex++];
            float x = pointComponents[componentIndex++];
            float y = pointComponents[componentIndex++];
            if (fraction == prevFraction && x != prevX) {
                throw new IllegalArgumentException(
                        "The Path cannot have discontinuity in the X axis.");
            }
            if (x < prevX) {
                throw new IllegalArgumentException("The Path cannot loop back on itself.");
            }
            mX[i] = x;
            mY[i] = y;
            prevX = x;
            prevFraction = fraction;
        }
    
private voidinitQuad(float controlX, float controlY)

        Path path = new Path();
        path.moveTo(0, 0);
        path.quadTo(controlX, controlY, 1f, 1f);
        initPath(path);
    
private voidparseInterpolatorFromTypeArray(android.content.res.TypedArray a)

        // If there is pathData defined in the xml file, then the controls points
        // will be all coming from pathData.
        if (a.hasValue(R.styleable.PathInterpolator_pathData)) {
            String pathData = a.getString(R.styleable.PathInterpolator_pathData);
            Path path = PathParser.createPathFromPathData(pathData);
            if (path == null) {
                throw new InflateException("The path is null, which is created"
                        + " from " + pathData);
            }
            initPath(path);
        } else {
            if (!a.hasValue(R.styleable.PathInterpolator_controlX1)) {
                throw new InflateException("pathInterpolator requires the controlX1 attribute");
            } else if (!a.hasValue(R.styleable.PathInterpolator_controlY1)) {
                throw new InflateException("pathInterpolator requires the controlY1 attribute");
            }
            float x1 = a.getFloat(R.styleable.PathInterpolator_controlX1, 0);
            float y1 = a.getFloat(R.styleable.PathInterpolator_controlY1, 0);

            boolean hasX2 = a.hasValue(R.styleable.PathInterpolator_controlX2);
            boolean hasY2 = a.hasValue(R.styleable.PathInterpolator_controlY2);

            if (hasX2 != hasY2) {
                throw new InflateException(
                        "pathInterpolator requires both controlX2 and controlY2 for cubic Beziers.");
            }

            if (!hasX2) {
                initQuad(x1, y1);
            } else {
                float x2 = a.getFloat(R.styleable.PathInterpolator_controlX2, 0);
                float y2 = a.getFloat(R.styleable.PathInterpolator_controlY2, 0);
                initCubic(x1, y1, x2, y2);
            }
        }