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.util.AttributeSet;
import android.view.ViewParent;
import androidx.annotation.NonNull;
import androidx.constraintlayout.motion.widget.MotionLayout;
import androidx.constraintlayout.widget.R;
/**
* 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[] mVelocity = 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 count = a.getIndexCount();
for (int i = 0; i < count; 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();
}
/**
* set the text
* @param text
*/
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(@NonNull 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, mVelocity, mVelocityMode);
mInvertMatrix.mapVectors(mVelocity);
float sx = (width * px);
float sy = (height * py);
float ex = sx - (mVelocity[0] * mTailScale);
float ey = sy - (mVelocity[1] * mTailScale);
mInvertMatrix.mapVectors(mVelocity);
canvas.drawLine(sx, sy, ex, ey, mPaintTelltales);
}
}
}
}