Skip to content
This repository was archived by the owner on Dec 27, 2024. It is now read-only.

Commit a2e88f3

Browse files
committed
fix relative motion support
1 parent de43583 commit a2e88f3

File tree

6 files changed

+91
-21
lines changed

6 files changed

+91
-21
lines changed

constraintlayout/core/src/main/java/androidx/constraintlayout/core/motion/Motion.java

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
import androidx.constraintlayout.core.motion.utils.KeyCache;
3232
import androidx.constraintlayout.core.motion.utils.KeyCycleOscillator;
3333
import androidx.constraintlayout.core.motion.utils.KeyFrameArray;
34+
import androidx.constraintlayout.core.motion.utils.NonNull;
35+
import androidx.constraintlayout.core.motion.utils.Nullable;
3436
import androidx.constraintlayout.core.motion.utils.Rect;
3537
import androidx.constraintlayout.core.motion.utils.SplineSet;
3638
import androidx.constraintlayout.core.motion.utils.TimeCycleSplineSet;
@@ -78,7 +80,7 @@ public class Motion implements TypedValues {
7880
private static final boolean DEBUG = false;
7981
private static final boolean FAVOR_FIXED_SIZE_VIEWS = false;
8082
MotionWidget mView;
81-
int mId;
83+
public String mId;
8284
String mConstraintTag;
8385
private int mCurveFitType = UNSET;
8486
private MotionPaths mStartMotionPath = new MotionPaths();
@@ -125,7 +127,7 @@ public class Motion implements TypedValues {
125127
private float mQuantizeMotionPhase = Float.NaN;
126128
private DifferentialInterpolator mQuantizeMotionInterpolator = null;
127129
private boolean mNoMovement = false;
128-
130+
Motion mRelativeMotion;
129131
/**
130132
* Get the view to pivot around
131133
*
@@ -237,16 +239,25 @@ public float getFinalHeight() {
237239
*
238240
* @return the view id of the view this is in polar mode to or -1 if not in polar
239241
*/
240-
public int getAnimateRelativeTo() {
242+
@Nullable
243+
public String getAnimateRelativeTo() {
241244
return mStartMotionPath.mAnimateRelativeTo;
242245
}
243246

244247
/**
245-
* @TODO: add description
248+
* set up the motion to be relative to this other motionController
246249
*/
247250
public void setupRelative(Motion motionController) {
248-
mStartMotionPath.setupRelative(motionController, motionController.mStartMotionPath);
249-
mEndMotionPath.setupRelative(motionController, motionController.mEndMotionPath);
251+
mRelativeMotion = motionController;
252+
}
253+
private void setupRelative() {
254+
if (mRelativeMotion == null) {
255+
return;
256+
}
257+
Utils.log("start ");
258+
mStartMotionPath.setupRelative(mRelativeMotion, mRelativeMotion.mStartMotionPath);
259+
Utils.log("end");
260+
mEndMotionPath.setupRelative(mRelativeMotion, mRelativeMotion.mEndMotionPath);
250261
}
251262

252263
public float getCenterX() {
@@ -673,6 +684,8 @@ public void setup(int parentWidth,
673684
HashSet<String> cycleAttributes = new HashSet<>(); // attributes we need to oscillate
674685
HashMap<String, Integer> interpolation = new HashMap<>();
675686
ArrayList<MotionKeyTrigger> triggerList = null;
687+
688+
setupRelative();
676689
if (DEBUG) {
677690
if (mKeyList == null) {
678691
Utils.log(TAG, ">>>>>>>>>>>>>>> mKeyList==null");
@@ -1722,7 +1735,11 @@ public boolean setValue(int id, String value) {
17221735
mQuantizeMotionInterpolator = getInterpolator(SPLINE_STRING, value, 0);
17231736
return true;
17241737
}
1725-
1738+
if ( MotionType.TYPE_ANIMATE_RELATIVE_TO == id) {
1739+
mStartMotionPath.mAnimateRelativeTo = value;
1740+
Utils.logStack("mAnimateRelativeTo= "+value,6);
1741+
return true;
1742+
}
17261743
return false;
17271744
}
17281745

@@ -1763,4 +1780,9 @@ public void setStaggerOffset(float staggerOffset) {
17631780
public float getMotionStagger() {
17641781
return mMotionStagger;
17651782
}
1783+
1784+
public void setIdString(String stringId) {
1785+
mId = stringId;
1786+
mStartMotionPath.mId = mId;
1787+
}
17661788
}

constraintlayout/core/src/main/java/androidx/constraintlayout/core/motion/MotionPaths.java

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ public class MotionPaths implements Comparable<MotionPaths> {
4747
public static final int CARTESIAN = MotionKeyPosition.TYPE_CARTESIAN;
4848
public static final int SCREEN = MotionKeyPosition.TYPE_SCREEN;
4949
static String[] sNames = {"position", "x", "y", "width", "height", "pathRotate"};
50+
public String mId;
5051
Easing mKeyFrameEasing;
5152
int mDrawPath = 0;
5253
float mTime;
@@ -58,7 +59,7 @@ public class MotionPaths implements Comparable<MotionPaths> {
5859
float mPathRotate = Float.NaN;
5960
float mProgress = Float.NaN;
6061
int mPathMotionArc = UNSET;
61-
int mAnimateRelativeTo = UNSET;
62+
String mAnimateRelativeTo = null;
6263
float mRelativeAngle = Float.NaN;
6364
Motion mRelativeToController = null;
6465

@@ -121,7 +122,8 @@ public MotionPaths(int parentWidth,
121122
MotionKeyPosition c,
122123
MotionPaths startTimePoint,
123124
MotionPaths endTimePoint) {
124-
if (startTimePoint.mAnimateRelativeTo != UNSET) {
125+
Utils.log(" ===================== setup start "+startTimePoint.mId+" : "+ startTimePoint.mAnimateRelativeTo );
126+
if (startTimePoint.mAnimateRelativeTo != null) {
125127
initPolar(parentWidth, parentHeight, c, startTimePoint, endTimePoint);
126128
return;
127129
}
@@ -157,6 +159,9 @@ void initPolar(int parentWidth,
157159
mHeight = (int) (s.mHeight + scaleY * scaleHeight);
158160
float startfactor = 1 - position;
159161
float endfactor = position;
162+
Utils.log(mId+": start "+s.mX+","+s.mY);
163+
Utils.log(mId+": end "+e.mX+","+e.mY);
164+
Utils.log(mId+": mAnimateRelativeTo "+e.mAnimateRelativeTo);
160165
switch (c.mPositionType) {
161166
case MotionKeyPosition.TYPE_SCREEN:
162167
this.mX = Float.isNaN(c.mPercentX) ? (position * (e.mX - s.mX) + s.mX)
@@ -192,12 +197,17 @@ public void setupRelative(Motion mc, MotionPaths relative) {
192197
double dx = mX + mWidth / 2 - relative.mX - relative.mWidth / 2;
193198
double dy = mY + mHeight / 2 - relative.mY - relative.mHeight / 2;
194199
mRelativeToController = mc;
195-
200+
Utils.log(mId+": my === "+mX+" , "+mY);
201+
Utils.log(mId+": relative === "+relative.mX+" , "+relative.mY);
202+
Utils.log(mId+": delta === "+dx+" , "+dy);
196203
mX = (float) Math.hypot(dy, dx);
197204
if (Float.isNaN(mRelativeAngle)) {
205+
198206
mY = (float) (Math.atan2(dy, dx) + Math.PI / 2);
207+
Utils.log(mId+": compute === "+Math.toDegrees(mY));
199208
} else {
200209
mY = (float) Math.toRadians(mRelativeAngle);
210+
Utils.log(mId+": defined === "+Math.toDegrees(mY));
201211

202212
}
203213
}
@@ -926,7 +936,7 @@ public void applyParameters(MotionWidget c) {
926936
point.mDrawPath = c.mMotion.mDrawPath;
927937
point.mAnimateCircleAngleTo = c.mMotion.mAnimateCircleAngleTo;
928938
point.mProgress = c.mPropertySet.mProgress;
929-
point.mRelativeAngle = 0; // c.layout.circleAngle;
939+
// point.mRelativeAngle = 0; // c.layout.circleAngle;
930940
Set<String> at = c.getCustomAttributeNames();
931941
for (String s : at) {
932942
CustomVariable attr = c.getCustomAttribute(s);

constraintlayout/core/src/main/java/androidx/constraintlayout/core/motion/MotionWidget.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public class MotionWidget implements TypedValues {
5757
* @DoNotShow
5858
*/
5959
public static class Motion {
60-
public int mAnimateRelativeTo = UNSET;
60+
public String mAnimateRelativeTo = null;
6161
public int mAnimateCircleAngleTo = 0;
6262
public String mTransitionEasing = null;
6363
public int mPathMotionArc = UNSET;
@@ -166,6 +166,10 @@ public boolean setValue(int id, float value) {
166166

167167
@Override
168168
public boolean setValue(int id, String value) {
169+
if (id == MotionType.TYPE_ANIMATE_RELATIVE_TO) {
170+
mMotion.mAnimateRelativeTo = value;
171+
return true;
172+
}
169173
return setValueMotion(id, value);
170174
}
171175

@@ -179,9 +183,6 @@ public boolean setValue(int id, boolean value) {
179183
*/
180184
public boolean setValueMotion(int id, int value) {
181185
switch (id) {
182-
case MotionType.TYPE_ANIMATE_RELATIVE_TO:
183-
mMotion.mAnimateRelativeTo = value;
184-
break;
185186
case MotionType.TYPE_ANIMATE_CIRCLEANGLE_TO:
186187
mMotion.mAnimateCircleAngleTo = value;
187188
break;

constraintlayout/core/src/main/java/androidx/constraintlayout/core/state/Transition.java

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -710,11 +710,31 @@ public void addCustomColor(int state, String widgetId, String property, int colo
710710
public void updateFrom(ConstraintWidgetContainer container, int state) {
711711
final ArrayList<ConstraintWidget> children = container.getChildren();
712712
final int count = children.size();
713+
WidgetState [] states = new WidgetState[count];
714+
boolean relative = false;
713715
for (int i = 0; i < count; i++) {
714716
ConstraintWidget child = children.get(i);
715717
WidgetState widgetState = getWidgetState(child.stringId, null, state);
718+
states[i] = widgetState;
716719
widgetState.update(child, state);
720+
String id = widgetState.getPathRelativeId();
721+
if (id != null) {
722+
relative = true;
723+
}
717724
}
725+
if (relative) {
726+
for (int i = 0; i < count; i++) {
727+
ConstraintWidget child = children.get(i);
728+
WidgetState widgetState = getWidgetState(child.stringId, null, state);
729+
states[i] = widgetState;
730+
String id = widgetState.getPathRelativeId();
731+
if (id != null) {
732+
widgetState.setPathRelative(getWidgetState(id, null, state));
733+
734+
}
735+
}
736+
}
737+
718738
calcStagger();
719739
}
720740

@@ -844,6 +864,7 @@ static class WidgetState {
844864
WidgetFrame mEnd;
845865
WidgetFrame mInterpolated;
846866
Motion mMotionControl;
867+
boolean mNeedSetup = true;
847868
MotionWidget mMotionWidgetStart;
848869
MotionWidget mMotionWidgetEnd;
849870
MotionWidget mMotionWidgetInterpolated;
@@ -886,13 +907,23 @@ public void update(ConstraintWidget child, int state) {
886907
mStart.update(child);
887908
mMotionWidgetStart.updateMotion(mMotionWidgetStart);
888909
mMotionControl.setStart(mMotionWidgetStart);
910+
mNeedSetup = true;
889911
} else if (state == END) {
890912
mEnd.update(child);
891913
mMotionControl.setEnd(mMotionWidgetEnd);
914+
mNeedSetup = true;
892915
}
893916
mParentWidth = -1;
894917
}
895918

919+
/**
920+
* Return the id of the widget to animate relative to
921+
* @return id of widget or null
922+
*/
923+
String getPathRelativeId() {
924+
return mMotionControl.getAnimateRelativeTo();
925+
}
926+
896927
public WidgetFrame getFrame(int type) {
897928
if (type == START) {
898929
return mStart;
@@ -909,14 +940,20 @@ public void interpolate(int parentWidth,
909940
// TODO only update if parentHeight != mParentHeight || parentWidth != mParentWidth) {
910941
mParentHeight = parentHeight;
911942
mParentWidth = parentWidth;
912-
mMotionControl.setup(parentWidth, parentHeight, 1, System.nanoTime());
913-
943+
if (mNeedSetup) {
944+
mMotionControl.setup(parentWidth, parentHeight, 1, System.nanoTime());
945+
mNeedSetup = false;
946+
}
914947
WidgetFrame.interpolate(parentWidth, parentHeight,
915948
mInterpolated, mStart, mEnd, transition, progress);
916949
mInterpolated.interpolatedPos = progress;
917950
mMotionControl.interpolate(mMotionWidgetInterpolated,
918951
progress, System.nanoTime(), mKeyCache);
919952
}
953+
954+
public void setPathRelative(WidgetState widgetState) {
955+
mMotionControl.setupRelative( widgetState.mMotionControl);
956+
}
920957
}
921958

922959
static class KeyPosition {

projects/ComposeConstraintLayout/app/src/main/java/com/example/constraintlayout/ConstraintMotionProps.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -742,7 +742,7 @@ fun MotionOrbit1() {
742742
box1: {
743743
width: 50, height: 50,
744744
bottom: ['parent', 'bottom', 10],
745-
start: ['parent', 'start', 10],
745+
start: ['parent', 'start', 80],
746746
},
747747
title: {
748748
top: ['parent', 'top', 10],
@@ -754,7 +754,6 @@ fun MotionOrbit1() {
754754
bottom: ['parent', 'bottom', 10],
755755
start: ['parent', 'start', 10],
756756
motion: {
757-
pathArc : 'startHorizontal',
758757
relativeTo: 'box1'
759758
}
760759
}
@@ -763,7 +762,7 @@ fun MotionOrbit1() {
763762
box1: {
764763
width: 50, height: 50,
765764
top: ['parent', 'top', 60],
766-
end: ['parent', 'end', 60],
765+
end: ['parent', 'end', 80],
767766
},
768767
title: {
769768
top: ['parent', 'top', 10],

projects/ComposeConstraintLayout/app/src/main/java/com/example/constraintlayout/MainActivity.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ import com.google.accompanist.coil.rememberCoilPainter
3737
class MainActivity : AppCompatActivity() {
3838
private var mFrameLayout: FrameLayout? = null
3939
private var composeNum = 0
40-
private val START_NUMBER = 48
40+
private val START_NUMBER = 58
4141
private var demos:ArrayList<CompFunc> = ArrayList()
4242
var map = HashMap<Int, String>();
4343
val linkServer = LinkServer()
@@ -162,6 +162,7 @@ class MainActivity : AppCompatActivity() {
162162
demos.add(object : CompFunc { @Composable override fun Run() { MotionQuantize2() } })
163163
demos.add(object : CompFunc { @Composable override fun Run() { MotionStagger1() } })
164164
demos.add(object : CompFunc { @Composable override fun Run() { MotionStagger2() } })
165+
demos.add(object : CompFunc { @Composable override fun Run() { MotionOrbit1() } })
165166

166167
demos.add(object : CompFunc { @Composable override fun Run() { Example () } })
167168
demos.add(object : CompFunc { @Composable override fun Run() { RowColExample () } })

0 commit comments

Comments
 (0)