MotionTelltales.java

/*
 * Copyright (C) 2018 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 androidx.constraintlayout.utils.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import androidx.constraintlayout.widget.R;
import androidx.constraintlayout.motion.widget.Debug;
import androidx.constraintlayout.motion.widget.MotionLayout;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.view.ViewParent;

/**
 * A view that is useful for prototyping Views that will move in MotionLayout. <b>Added in 2.0</b>
 * <p>
 * This view works with MotionLayout to demonstrate the motion of 25 points on the view.
 * It is based on MockView which draws a label (by default the view id),
 * along with diagonals.
 *
 * Useful as a deeper understanding of the motion of a view in a MotionLayout
 *
 * </p>
 */
public class MotionTelltales extends MockView {
    private static final String TAG = "MotionTelltales";
    private Paint mPaintTelltales = new Paint();
    MotionLayout mMotionLayout;
    float []velocity = new float[2];
    Matrix mInvertMatrix = new Matrix();
    int mVelocityMode = MotionLayout.VELOCITY_POST_LAYOUT;
    int mTailColor = Color.MAGENTA;
    float mTailScale = 0.25f;
    public MotionTelltales(Context context) {
        super(context);
        init( context, null);
    }

    public MotionTelltales(Context context, AttributeSet attrs) {
        super(context, attrs);
        init( context, attrs);
     }

    public MotionTelltales(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init( context, attrs);

    }
    private void init(Context context, AttributeSet attrs) {
        if (attrs != null) {
            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MotionTelltales);
            final int N = a.getIndexCount();
            for (int i = 0; i < N; i++) {
                int attr = a.getIndex(i);
                    if (attr == R.styleable.MotionTelltales_telltales_tailColor) {
                        mTailColor = a.getColor(attr, mTailColor);
                } else if (attr == R.styleable.MotionTelltales_telltales_velocityMode) {
                        mVelocityMode = a.getInt(attr, mVelocityMode);
                } else if (attr == R.styleable.MotionTelltales_telltales_tailScale) {
                        mTailScale = a.getFloat(attr, mTailScale);
                }
            }
            a.recycle();
        }
        mPaintTelltales.setColor(mTailColor);
        mPaintTelltales.setStrokeWidth(5);
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();

    }
    public void setText(CharSequence text) {
        mText = text.toString();
        requestLayout();
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        postInvalidate();
    }

    @Override
    public void onDraw(Canvas canvas) {
       super.onDraw(canvas);
        Matrix matrix = getMatrix();
        matrix.invert(mInvertMatrix);
        if (mMotionLayout == null) {
            ViewParent vp = getParent();
            if (vp instanceof MotionLayout){
                mMotionLayout = (MotionLayout) vp;
            }
            return;
        }
        int width = getWidth();
        int height = getHeight();
        float []f = {0.1f,0.25f,0.5f,0.75f,0.9f};
        for (int y = 0; y < f.length; y++) {
            float py = f[y];
            for (int x = 0; x < f.length; x++) {
                float px = f[x];
                mMotionLayout.getViewVelocity(this,px,py, velocity, mVelocityMode);
                mInvertMatrix.mapVectors(velocity);

                float sx =  (width*px);
                float sy =   (height*py);
                float ex = sx - (velocity[0]*mTailScale);
                float ey = sy -  (velocity[1]*mTailScale);
                mInvertMatrix.mapVectors(velocity);
                canvas.drawLine(sx,sy,ex,ey,mPaintTelltales);
            }

        }
//        Log.v(TAG, Debug.getLocation()+">>>>>>>>>>onDraw>>"+velocity[0]+","+velocity[1]+" dx,dy");

    }
}