java.lang.Object
↳androidx.constraintlayout.motion.widget.DesignTool
Gradle dependencies
compile group: 'androidx.constraintlayout', name: 'constraintlayout', version: '2.2.0-beta01'
- groupId: androidx.constraintlayout
- artifactId: constraintlayout
- version: 2.2.0-beta01
Artifact androidx.constraintlayout:constraintlayout:2.2.0-beta01 it located at Google repository (https://maven.google.com/)
Androidx artifact mapping:
androidx.constraintlayout:constraintlayout com.android.support.constraint:constraint-layout
Overview
Utility class to manipulate MotionLayout from the layout editor
Summary
Methods |
---|
public int | designAccess(int cmd, java.lang.String type, java.lang.Object viewObject, float[] in[], int inLength, float[] out[], int outLength)
This is a general access to systems in the MotionLayout System
This provides a series of commands used by the designer to access needed logic
It is written this way to minimize the interface between the library and designer. |
public void | disableAutoTransition(boolean disable)
this allow disabling autoTransitions to prevent design surface
from being in undefined states |
public void | dumpConstraintSet(java.lang.String set)
|
public int | getAnimationKeyFrames(java.lang.Object view, float[] key[])
Get the location of the start end and key frames |
public int | getAnimationPath(java.lang.Object view, float[] path[], int len)
Get the center point of the animation path of a view |
public void | getAnimationRectangles(java.lang.Object view, float[] path[])
Get the center point of the animation path of a view |
public java.lang.String | getEndState()
|
public java.lang.Object | getKeyframe(int type, int target, int position)
|
public java.lang.Object | getKeyframe(java.lang.Object view, int type, int position)
|
public java.lang.Object | getKeyframeAtLocation(java.lang.Object viewObject, float x, float y)
|
public int | getKeyFrameInfo(java.lang.Object view, int type, int[] info[])
Get the keyFrames for the view controlled by this MotionController. |
public float | getKeyFramePosition(java.lang.Object view, int type, float x, float y)
|
public int | getKeyFramePositions(java.lang.Object view, int[] type[], float[] pos[])
Get the keyFrames for the view controlled by this MotionController. |
public java.lang.Boolean | getPositionKeyframe(java.lang.Object keyFrame, java.lang.Object view, float x, float y, java.lang.String attribute[], float[] value[])
|
public float | getProgress()
Return the current progress of the current transition |
public java.lang.String | getStartState()
|
public java.lang.String | getState()
Return the current state (ConstraintSet id) as a string |
public long | getTransitionTimeMs()
Gets the time of the currently set animation. |
public boolean | isInTransition()
Utility method, returns true if we are currently in a transition |
public void | setAttributes(int dpi, java.lang.String constraintSetId, java.lang.Object opaqueView, java.lang.Object opaqueAttributes)
Live setting of attributes on a view |
public void | setKeyFrame(java.lang.Object view, int position, java.lang.String name, java.lang.Object value)
|
public void | setKeyframe(java.lang.Object keyFrame, java.lang.String tag, java.lang.Object value)
|
public boolean | setKeyFramePosition(java.lang.Object view, int position, int type, float x, float y)
Move the widget directly |
public void | setState(java.lang.String id)
This sets the constraint set based on a string. |
public void | setToolPosition(float position)
|
public void | setTransition(java.lang.String start, java.lang.String end)
This sets the constraint set based on a string. |
public void | setViewDebug(java.lang.Object view, int debugMode)
|
from java.lang.Object | clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Constructors
Methods
public int
getAnimationPath(java.lang.Object view, float[] path[], int len)
Get the center point of the animation path of a view
Parameters:
view: view to getMap the animation of
path: array to be filled (x1,y1,x2,y2...)
Returns:
-1 if not under and animation 0 if not animated or number of point along animation
public void
getAnimationRectangles(java.lang.Object view, float[] path[])
Get the center point of the animation path of a view
Parameters:
view: view to getMap the animation of
path: array to be filled (in groups of 8) (x1,y1,x2,y2...)
public int
getAnimationKeyFrames(java.lang.Object view, float[] key[])
Get the location of the start end and key frames
Parameters:
view: the view to track
key: array to be filled
Returns:
number of key frames + 2
public void
setToolPosition(float position)
Parameters:
position:
public java.lang.String
getStartState()
Returns:
public java.lang.String
getEndState()
Returns:
public float
getProgress()
Return the current progress of the current transition
Returns:
current transition's progress
public java.lang.String
getState()
Return the current state (ConstraintSet id) as a string
Returns:
the last state set via the design tool bridge
public void
setState(java.lang.String id)
This sets the constraint set based on a string. (without the "@+id/")
Parameters:
id:
public boolean
isInTransition()
Utility method, returns true if we are currently in a transition
Returns:
true if in a transition, false otherwise
public void
setTransition(java.lang.String start, java.lang.String end)
This sets the constraint set based on a string. (without the "@+id/")
Parameters:
start:
end:
public void
disableAutoTransition(boolean disable)
this allow disabling autoTransitions to prevent design surface
from being in undefined states
Parameters:
disable:
public long
getTransitionTimeMs()
Gets the time of the currently set animation.
Returns:
time in Milliseconds
public int
getKeyFramePositions(java.lang.Object view, int[] type[], float[] pos[])
Get the keyFrames for the view controlled by this MotionController.
The call is designed to be efficient because it will be called 30x Number of views a second
Parameters:
view: the view to return keyframe positions
type: is pos(0-100) + 1000*mType(1=Attrib, 2=Position, 3=TimeCycle 4=Cycle 5=Trigger
pos: the x&y position of the keyFrame along the path
Returns:
Number of keyFrames found
public int
getKeyFrameInfo(java.lang.Object view, int type, int[] info[])
Get the keyFrames for the view controlled by this MotionController.
The call is designed to be efficient because it will be called 30x Number of views a second
Parameters:
view: the view to return keyframe positions
info:
Returns:
Number of keyFrames found
public float
getKeyFramePosition(java.lang.Object view, int type, float x, float y)
Parameters:
view:
type:
x:
y:
Returns:
public void
setKeyFrame(java.lang.Object view, int position, java.lang.String name, java.lang.Object value)
Parameters:
view:
position:
name:
value:
public boolean
setKeyFramePosition(java.lang.Object view, int position, int type, float x, float y)
Move the widget directly
Parameters:
view:
position:
type:
x:
y:
Returns:
public void
setViewDebug(java.lang.Object view, int debugMode)
Parameters:
view:
debugMode:
public int
designAccess(int cmd, java.lang.String type, java.lang.Object viewObject, float[] in[], int inLength, float[] out[], int outLength)
This is a general access to systems in the MotionLayout System
This provides a series of commands used by the designer to access needed logic
It is written this way to minimize the interface between the library and designer.
It allows the logic to be kept only in the library not replicated in the gui builder.
It also allows us to understand understand the version of MotionLayout in use
commands
0 return the version number
1 Get the center point of the animation path of a view
2 Get the location of the start end and key frames
Parameters:
cmd: this provide the command needed
type: support argument for command
viewObject: if this command references a view this provides access
in: this allows for an array of float to be the input to the system
inLength: this provides the length of the input
out: this provide the output array
outLength: the length of the output array
Returns:
command dependent -1 is typically an error (do not understand)
public java.lang.Object
getKeyframe(int type, int target, int position)
Parameters:
type:
target:
position:
Returns:
public java.lang.Object
getKeyframeAtLocation(java.lang.Object viewObject, float x, float y)
Parameters:
viewObject:
x:
y:
Returns:
public java.lang.Boolean
getPositionKeyframe(java.lang.Object keyFrame, java.lang.Object view, float x, float y, java.lang.String attribute[], float[] value[])
Parameters:
keyFrame:
view:
x:
y:
attribute:
value:
Returns:
public java.lang.Object
getKeyframe(java.lang.Object view, int type, int position)
Parameters:
view:
type:
position:
Returns:
public void
setKeyframe(java.lang.Object keyFrame, java.lang.String tag, java.lang.Object value)
Parameters:
keyFrame:
tag:
value:
public void
setAttributes(int dpi, java.lang.String constraintSetId, java.lang.Object opaqueView, java.lang.Object opaqueAttributes)
Live setting of attributes on a view
Parameters:
dpi: dpi used by the application
constraintSetId: ConstraintSet id
opaqueView: the Android View we operate on, passed as an Object
opaqueAttributes: the list of attributes (hash) we pass to the view
public void
dumpConstraintSet(java.lang.String set)
Parameters:
set:
Source
/*
* 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.motion.widget;
import static androidx.constraintlayout.widget.ConstraintSet.BASELINE;
import static androidx.constraintlayout.widget.ConstraintSet.BOTTOM;
import static androidx.constraintlayout.widget.ConstraintSet.END;
import static androidx.constraintlayout.widget.ConstraintSet.HORIZONTAL;
import static androidx.constraintlayout.widget.ConstraintSet.LEFT;
import static androidx.constraintlayout.widget.ConstraintSet.RIGHT;
import static androidx.constraintlayout.widget.ConstraintSet.START;
import static androidx.constraintlayout.widget.ConstraintSet.TOP;
import static androidx.constraintlayout.widget.ConstraintSet.VERTICAL;
import static androidx.constraintlayout.widget.ConstraintSet.WRAP_CONTENT;
import android.util.Log;
import android.util.Pair;
import android.view.View;
import android.view.ViewGroup;
import androidx.constraintlayout.widget.ConstraintSet;
import java.util.HashMap;
import java.util.Objects;
/**
* Utility class to manipulate MotionLayout from the layout editor
*
*
*/
public class DesignTool {
static final HashMap<Pair<Integer, Integer>, String> sAllAttributes = new HashMap<>();
static final HashMap<String, String> sAllMargins = new HashMap<>();
private static final boolean DEBUG = false;
private static final boolean DO_NOT_USE = false;
private static final String TAG = "DesignTool";
static {
sAllAttributes.put(Pair.create(BOTTOM, BOTTOM), "layout_constraintBottom_toBottomOf");
sAllAttributes.put(Pair.create(BOTTOM, TOP), "layout_constraintBottom_toTopOf");
sAllAttributes.put(Pair.create(TOP, BOTTOM), "layout_constraintTop_toBottomOf");
sAllAttributes.put(Pair.create(TOP, TOP), "layout_constraintTop_toTopOf");
sAllAttributes.put(Pair.create(START, START), "layout_constraintStart_toStartOf");
sAllAttributes.put(Pair.create(START, END), "layout_constraintStart_toEndOf");
sAllAttributes.put(Pair.create(END, START), "layout_constraintEnd_toStartOf");
sAllAttributes.put(Pair.create(END, END), "layout_constraintEnd_toEndOf");
sAllAttributes.put(Pair.create(LEFT, LEFT), "layout_constraintLeft_toLeftOf");
sAllAttributes.put(Pair.create(LEFT, RIGHT), "layout_constraintLeft_toRightOf");
sAllAttributes.put(Pair.create(RIGHT, RIGHT), "layout_constraintRight_toRightOf");
sAllAttributes.put(Pair.create(RIGHT, LEFT), "layout_constraintRight_toLeftOf");
sAllAttributes.put(Pair.create(BASELINE, BASELINE),
"layout_constraintBaseline_toBaselineOf");
sAllMargins.put("layout_constraintBottom_toBottomOf", "layout_marginBottom");
sAllMargins.put("layout_constraintBottom_toTopOf", "layout_marginBottom");
sAllMargins.put("layout_constraintTop_toBottomOf", "layout_marginTop");
sAllMargins.put("layout_constraintTop_toTopOf", "layout_marginTop");
sAllMargins.put("layout_constraintStart_toStartOf", "layout_marginStart");
sAllMargins.put("layout_constraintStart_toEndOf", "layout_marginStart");
sAllMargins.put("layout_constraintEnd_toStartOf", "layout_marginEnd");
sAllMargins.put("layout_constraintEnd_toEndOf", "layout_marginEnd");
sAllMargins.put("layout_constraintLeft_toLeftOf", "layout_marginLeft");
sAllMargins.put("layout_constraintLeft_toRightOf", "layout_marginLeft");
sAllMargins.put("layout_constraintRight_toRightOf", "layout_marginRight");
sAllMargins.put("layout_constraintRight_toLeftOf", "layout_marginRight");
}
private final MotionLayout mMotionLayout;
private MotionScene mSceneCache;
private String mLastStartState = null;
private String mLastEndState = null;
private int mLastStartStateId = -1;
private int mLastEndStateId = -1;
public DesignTool(MotionLayout motionLayout) {
mMotionLayout = motionLayout;
}
private static int getPxFromDp(int dpi, String value) {
if (value == null) {
return 0;
}
int index = value.indexOf('d');
if (index == -1) {
return 0;
}
String filteredValue = value.substring(0, index);
int dpValue = (int) (Integer.valueOf(filteredValue) * dpi / 160f);
return dpValue;
}
private static void connect(int dpi,
ConstraintSet set,
View view,
HashMap<String, String> attributes,
int from,
int to) {
String connection = sAllAttributes.get(Pair.create(from, to));
String connectionValue = attributes.get(connection);
if (connectionValue != null) {
int marginValue = 0;
String margin = sAllMargins.get(connection);
if (margin != null) {
marginValue = getPxFromDp(dpi, attributes.get(margin));
}
int id = Integer.parseInt(connectionValue);
set.connect(view.getId(), from, id, to, marginValue);
}
}
private static void setBias(ConstraintSet set,
View view,
HashMap<String, String> attributes,
int type) {
String bias = "layout_constraintHorizontal_bias";
if (type == VERTICAL) {
bias = "layout_constraintVertical_bias";
}
String biasValue = attributes.get(bias);
if (biasValue != null) {
if (type == HORIZONTAL) {
set.setHorizontalBias(view.getId(), Float.parseFloat(biasValue));
} else if (type == VERTICAL) {
set.setVerticalBias(view.getId(), Float.parseFloat(biasValue));
}
}
}
private static void setDimensions(int dpi,
ConstraintSet set,
View view,
HashMap<String, String> attributes,
int type) {
String dimension = "layout_width";
if (type == VERTICAL) {
dimension = "layout_height";
}
String dimensionValue = attributes.get(dimension);
if (dimensionValue != null) {
int value = WRAP_CONTENT;
if (!dimensionValue.equalsIgnoreCase("wrap_content")) {
value = getPxFromDp(dpi, dimensionValue);
}
if (type == HORIZONTAL) {
set.constrainWidth(view.getId(), value);
} else {
set.constrainHeight(view.getId(), value);
}
}
}
private static void setAbsolutePositions(int dpi,
ConstraintSet set,
View view,
HashMap<String, String> attributes) {
String absoluteX = attributes.get("layout_editor_absoluteX");
if (absoluteX != null) {
set.setEditorAbsoluteX(view.getId(), getPxFromDp(dpi, absoluteX));
}
String absoluteY = attributes.get("layout_editor_absoluteY");
if (absoluteY != null) {
set.setEditorAbsoluteY(view.getId(), getPxFromDp(dpi, absoluteY));
}
}
/**
* Get the center point of the animation path of a view
*
* @param view view to getMap the animation of
* @param path array to be filled (x1,y1,x2,y2...)
* @return -1 if not under and animation 0 if not animated or number of point along animation
*/
public int getAnimationPath(Object view, float[] path, int len) {
if (mMotionLayout.mScene == null) {
return -1;
}
MotionController motionController = mMotionLayout.mFrameArrayList.get(view);
if (motionController == null) {
return 0;
}
motionController.buildPath(path, len);
return len;
}
/**
* Get the center point of the animation path of a view
*
* @param view view to getMap the animation of
* @param path array to be filled (in groups of 8) (x1,y1,x2,y2...)
*/
public void getAnimationRectangles(Object view, float[] path) {
if (mMotionLayout.mScene == null) {
return;
}
int duration = mMotionLayout.mScene.getDuration();
int frames = duration / 16;
MotionController motionController = mMotionLayout.mFrameArrayList.get(view);
if (motionController == null) {
return;
}
motionController.buildRectangles(path, frames);
}
/**
* Get the location of the start end and key frames
*
* @param view the view to track
* @param key array to be filled
* @return number of key frames + 2
*/
public int getAnimationKeyFrames(Object view, float[] key) {
if (mMotionLayout.mScene == null) {
return -1;
}
int duration = mMotionLayout.mScene.getDuration();
int frames = duration / 16;
MotionController motionController = mMotionLayout.mFrameArrayList.get(view);
if (motionController == null) {
return 0;
}
motionController.buildKeyFrames(key, null);
return frames;
}
/**
* @param position
*
*/
public void setToolPosition(float position) {
if (mMotionLayout.mScene == null) {
mMotionLayout.mScene = mSceneCache;
}
mMotionLayout.setProgress(position);
mMotionLayout.evaluate(true);
mMotionLayout.requestLayout();
mMotionLayout.invalidate();
}
// @TODO: add description
/**
*
* @return
*/
public String getStartState() {
int startId = mMotionLayout.getStartState();
if (mLastStartStateId == startId) {
return mLastStartState;
}
String last = mMotionLayout.getConstraintSetNames(startId);
if (last != null) {
mLastStartState = last;
mLastStartStateId = startId;
}
return mMotionLayout.getConstraintSetNames(startId);
}
// @TODO: add description
/**
*
* @return
*/
public String getEndState() {
int endId = mMotionLayout.getEndState();
if (mLastEndStateId == endId) {
return mLastEndState;
}
String last = mMotionLayout.getConstraintSetNames(endId);
if (last != null) {
mLastEndState = last;
mLastEndStateId = endId;
}
return last;
}
/**
* Return the current progress of the current transition
*
* @return current transition's progress
*/
public float getProgress() {
return mMotionLayout.getProgress();
}
/**
* Return the current state (ConstraintSet id) as a string
*
* @return the last state set via the design tool bridge
*/
public String getState() {
if (mLastStartState != null && mLastEndState != null) {
float progress = getProgress();
float epsilon = 0.01f;
if (progress <= epsilon) {
return mLastStartState;
} else if (progress >= 1 - epsilon) {
return mLastEndState;
}
}
return mLastStartState;
}
/**
* This sets the constraint set based on a string. (without the "@+id/")
*
* @param id
*/
public void setState(String id) {
if (id == null) {
id = "motion_base";
}
if (Objects.equals(mLastStartState, id)) {
return;
}
if (DEBUG) {
System.out.println("================================");
dumpConstraintSet(id);
}
mLastStartState = id;
mLastEndState = null;
if (id == null && DO_NOT_USE) { // going to base layout
if (mMotionLayout.mScene != null) {
mSceneCache = mMotionLayout.mScene;
mMotionLayout.mScene = null;
}
mMotionLayout.setProgress(0);
mMotionLayout.requestLayout();
}
if (mMotionLayout.mScene == null) {
mMotionLayout.mScene = mSceneCache;
}
int rscId = mMotionLayout.lookUpConstraintId(id);
mLastStartStateId = rscId;
if (rscId != 0) {
if (rscId == mMotionLayout.getStartState()) {
mMotionLayout.setProgress(0);
} else if (rscId == mMotionLayout.getEndState()) {
mMotionLayout.setProgress(1);
} else {
mMotionLayout.transitionToState(rscId);
mMotionLayout.setProgress(1);
}
}
mMotionLayout.requestLayout();
}
/**
* Utility method, returns true if we are currently in a transition
*
* @return true if in a transition, false otherwise
*/
public boolean isInTransition() {
return mLastStartState != null && mLastEndState != null;
}
/**
* This sets the constraint set based on a string. (without the "@+id/")
*
* @param start
* @param end
*/
public void setTransition(String start, String end) {
if (mMotionLayout.mScene == null) {
mMotionLayout.mScene = mSceneCache;
}
int startId = mMotionLayout.lookUpConstraintId(start);
int endId = mMotionLayout.lookUpConstraintId(end);
mMotionLayout.setTransition(startId, endId);
mLastStartStateId = startId;
mLastEndStateId = endId;
mLastStartState = start;
mLastEndState = end;
}
/**
* this allow disabling autoTransitions to prevent design surface
* from being in undefined states
*
* @param disable
*/
public void disableAutoTransition(boolean disable) {
mMotionLayout.disableAutoTransition(disable);
}
/**
* Gets the time of the currently set animation.
*
* @return time in Milliseconds
*/
public long getTransitionTimeMs() {
return mMotionLayout.getTransitionTimeMs();
}
/**
* Get the keyFrames for the view controlled by this MotionController.
* The call is designed to be efficient because it will be called 30x Number of views a second
*
* @param view the view to return keyframe positions
* @param type is pos(0-100) + 1000*mType(1=Attrib, 2=Position, 3=TimeCycle 4=Cycle 5=Trigger
* @param pos the x&y position of the keyFrame along the path
* @return Number of keyFrames found
*/
public int getKeyFramePositions(Object view, int[] type, float[] pos) {
MotionController controller = mMotionLayout.mFrameArrayList.get((View) view);
if (controller == null) {
return 0;
}
return controller.getKeyFramePositions(type, pos);
}
/**
* Get the keyFrames for the view controlled by this MotionController.
* The call is designed to be efficient because it will be called 30x Number of views a second
*
* @param view the view to return keyframe positions
* @param info
* @return Number of keyFrames found
*/
public int getKeyFrameInfo(Object view, int type, int[] info) {
MotionController controller = mMotionLayout.mFrameArrayList.get((View) view);
if (controller == null) {
return 0;
}
return controller.getKeyFrameInfo(type, info);
}
/**
* @param view
* @param type
* @param x
* @param y
* @return
*
*/
public float getKeyFramePosition(Object view, int type, float x, float y) {
if (!(view instanceof View)) {
return 0f;
}
MotionController mc = mMotionLayout.mFrameArrayList.get((View) view);
if (mc == null) {
return 0f;
}
return mc.getKeyFrameParameter(type, x, y);
}
/**
* @param view
* @param position
* @param name
* @param value
*
*/
public void setKeyFrame(Object view, int position, String name, Object value) {
if (DEBUG) {
Log.v(TAG, "setKeyFrame " + position + " <" + name + "> " + value);
}
if (mMotionLayout.mScene != null) {
mMotionLayout.mScene.setKeyframe((View) view, position, name, value);
mMotionLayout.mTransitionGoalPosition = position / 100f;
mMotionLayout.mTransitionLastPosition = 0;
mMotionLayout.rebuildScene();
mMotionLayout.evaluate(true);
}
}
/**
* Move the widget directly
*
* @param view
* @param position
* @param type
* @param x
* @param y
* @return
*
*/
public boolean setKeyFramePosition(Object view, int position, int type, float x, float y) {
if (!(view instanceof View)) {
return false;
}
if (mMotionLayout.mScene != null) {
MotionController controller = mMotionLayout.mFrameArrayList.get(view);
position = (int) (mMotionLayout.mTransitionPosition * 100);
if (controller != null
&& mMotionLayout.mScene.hasKeyFramePosition((View) view, position)) {
float fx = controller.getKeyFrameParameter(MotionController.HORIZONTAL_PATH_X,
x, y);
float fy = controller.getKeyFrameParameter(MotionController.VERTICAL_PATH_Y,
x, y);
// TODO: supports path relative
mMotionLayout.mScene.setKeyframe((View) view, position, "motion:percentX", fx);
mMotionLayout.mScene.setKeyframe((View) view, position, "motion:percentY", fy);
mMotionLayout.rebuildScene();
mMotionLayout.evaluate(true);
mMotionLayout.invalidate();
return true;
}
}
return false;
}
/**
* @param view
* @param debugMode
*
*/
public void setViewDebug(Object view, int debugMode) {
if (!(view instanceof View)) {
return;
}
MotionController motionController = mMotionLayout.mFrameArrayList.get(view);
if (motionController != null) {
motionController.setDrawPath(debugMode);
mMotionLayout.invalidate();
}
}
/**
* This is a general access to systems in the MotionLayout System
* This provides a series of commands used by the designer to access needed logic
* It is written this way to minimize the interface between the library and designer.
* It allows the logic to be kept only in the library not replicated in the gui builder.
* It also allows us to understand understand the version of MotionLayout in use
* commands
* 0 return the version number
* 1 Get the center point of the animation path of a view
* 2 Get the location of the start end and key frames
*
* @param cmd this provide the command needed
* @param type support argument for command
* @param viewObject if this command references a view this provides access
* @param in this allows for an array of float to be the input to the system
* @param inLength this provides the length of the input
* @param out this provide the output array
* @param outLength the length of the output array
* @return command dependent -1 is typically an error (do not understand)
*/
public int designAccess(int cmd, String type, Object viewObject,
float[] in, int inLength, float[] out, int outLength) {
View view = (View) viewObject;
MotionController motionController = null;
if (cmd != 0) {
if (mMotionLayout.mScene == null) {
return -1;
}
if (view != null) { // Can't find the view
motionController = mMotionLayout.mFrameArrayList.get(view);
if (motionController == null) {
return -1;
}
} else { // currently only cmd == 0 does not require a motion view
return -1;
}
}
switch (cmd) {
case 0: // version
return 1;
case 1: { // get View path
int duration = mMotionLayout.mScene.getDuration();
int frames = duration / 16;
motionController.buildPath(out, frames);
return frames;
}
case 2: { // get key frames
int duration = mMotionLayout.mScene.getDuration();
int frames = duration / 16;
motionController.buildKeyFrames(out, null);
return frames;
}
case 3: { // get Attribute
int duration = mMotionLayout.mScene.getDuration();
@SuppressWarnings("unused") int frames = duration / 16;
return motionController.getAttributeValues(type, out, outLength);
}
default:
return -1;
}
}
// @TODO: add description
/**
*
* @param type
* @param target
* @param position
* @return
*/
public Object getKeyframe(int type, int target, int position) {
if (mMotionLayout.mScene == null) {
return null;
}
return mMotionLayout.mScene.getKeyFrame(mMotionLayout.getContext(), type, target, position);
}
// @TODO: add description
/**
*
* @param viewObject
* @param x
* @param y
* @return
*/
public Object getKeyframeAtLocation(Object viewObject, float x, float y) {
View view = (View) viewObject;
MotionController motionController = null;
if (mMotionLayout.mScene == null) {
return -1;
}
if (view != null) { // Can't find the view
motionController = mMotionLayout.mFrameArrayList.get(view);
if (motionController == null) {
return null;
}
} else {
return null;
}
ViewGroup viewGroup = ((ViewGroup) view.getParent());
int layoutWidth = viewGroup.getWidth();
int layoutHeight = viewGroup.getHeight();
return motionController.getPositionKeyframe(layoutWidth, layoutHeight, x, y);
}
// @TODO: add description
/**
*
* @param keyFrame
* @param view
* @param x
* @param y
* @param attribute
* @param value
* @return
*/
public Boolean getPositionKeyframe(Object keyFrame,
Object view,
float x,
float y,
String[] attribute,
float[] value) {
if (keyFrame instanceof KeyPositionBase) {
KeyPositionBase key = (KeyPositionBase) keyFrame;
MotionController motionController = mMotionLayout.mFrameArrayList.get((View) view);
motionController.positionKeyframe((View) view, key, x, y, attribute, value);
mMotionLayout.rebuildScene();
mMotionLayout.mInTransition = true;
return true;
}
return false;
}
// @TODO: add description
/**
*
* @param view
* @param type
* @param position
* @return
*/
public Object getKeyframe(Object view, int type, int position) {
if (mMotionLayout.mScene == null) {
return null;
}
int target = ((View) view).getId();
return mMotionLayout.mScene.getKeyFrame(mMotionLayout.getContext(), type, target, position);
}
// @TODO: add description
/**
*
* @param keyFrame
* @param tag
* @param value
*/
public void setKeyframe(Object keyFrame, String tag, Object value) {
if (keyFrame instanceof Key) {
Key key = (Key) keyFrame;
key.setValue(tag, value);
mMotionLayout.rebuildScene();
mMotionLayout.mInTransition = true;
}
}
/**
* Live setting of attributes on a view
*
* @param dpi dpi used by the application
* @param constraintSetId ConstraintSet id
* @param opaqueView the Android View we operate on, passed as an Object
* @param opaqueAttributes the list of attributes (hash<string,string>) we pass to the view
*/
public void setAttributes(int dpi,
String constraintSetId,
Object opaqueView,
Object opaqueAttributes) {
View view = (View) opaqueView;
@SuppressWarnings("unchecked")
HashMap<String, String> attributes = (opaqueAttributes instanceof HashMap) ?
(HashMap<String, String>) opaqueAttributes : new HashMap<>();
int rscId = mMotionLayout.lookUpConstraintId(constraintSetId);
ConstraintSet set = mMotionLayout.mScene.getConstraintSet(rscId);
if (DEBUG) {
Log.v(TAG, "constraintSetId = " + constraintSetId + " " + rscId);
}
if (set == null) {
return;
}
set.clear(view.getId());
setDimensions(dpi, set, view, attributes, HORIZONTAL);
setDimensions(dpi, set, view, attributes, VERTICAL);
connect(dpi, set, view, attributes, START, START);
connect(dpi, set, view, attributes, START, END);
connect(dpi, set, view, attributes, END, END);
connect(dpi, set, view, attributes, END, START);
connect(dpi, set, view, attributes, LEFT, LEFT);
connect(dpi, set, view, attributes, LEFT, RIGHT);
connect(dpi, set, view, attributes, RIGHT, RIGHT);
connect(dpi, set, view, attributes, RIGHT, LEFT);
connect(dpi, set, view, attributes, TOP, TOP);
connect(dpi, set, view, attributes, TOP, BOTTOM);
connect(dpi, set, view, attributes, BOTTOM, TOP);
connect(dpi, set, view, attributes, BOTTOM, BOTTOM);
connect(dpi, set, view, attributes, BASELINE, BASELINE);
setBias(set, view, attributes, HORIZONTAL);
setBias(set, view, attributes, VERTICAL);
setAbsolutePositions(dpi, set, view, attributes);
mMotionLayout.updateState(rscId, set);
mMotionLayout.requestLayout();
}
// @TODO: add description
/**
*
* @param set
*/
public void dumpConstraintSet(String set) {
if (mMotionLayout.mScene == null) {
mMotionLayout.mScene = mSceneCache;
}
int setId = mMotionLayout.lookUpConstraintId(set);
System.out.println(" dumping " + set + " (" + setId + ")");
try {
mMotionLayout.mScene.getConstraintSet(setId).dump(mMotionLayout.mScene);
} catch (Exception ex) {
Log.e(TAG, "Error while dumping: " + set + " (" + setId + ")", ex);
}
}
}