diff --git a/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/helper/widget/Grid.java b/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/helper/widget/Grid.java index aa51d695b..0affa8fd8 100644 --- a/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/helper/widget/Grid.java +++ b/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/helper/widget/Grid.java @@ -26,7 +26,6 @@ import android.view.View; import androidx.constraintlayout.widget.ConstraintLayout; -import androidx.constraintlayout.widget.ConstraintSet; import androidx.constraintlayout.widget.R; import androidx.constraintlayout.widget.VirtualLayout; @@ -84,9 +83,11 @@ public class Grid extends VirtualLayout { private static final String TAG = "Grid"; public static final int VERTICAL = 1; public static final int HORIZONTAL = 0; + private static final boolean DEBUG_BOXES = false; private final int mMaxRows = 50; // maximum number of rows can be specified. private final int mMaxColumns = 50; // maximum number of columns can be specified. - private final ConstraintSet mConstraintSet = new ConstraintSet(); + // private final ConstraintSet mConstraintSet = new ConstraintSet(); + private View[] mBoxViews; ConstraintLayout mContainer; @@ -209,11 +210,11 @@ protected void init(AttributeSet attrs) { mStrSpans = a.getString(attr); } else if (attr == R.styleable.Grid_grid_skips) { mStrSkips = a.getString(attr); - } else if (attr == R.styleable.Grid_grid_rowWeights) { + } else if (attr == R.styleable.Grid_grid_rowWeights) { mStrRowWeights = a.getString(attr); - } else if (attr == R.styleable.Grid_grid_columnWeights) { + } else if (attr == R.styleable.Grid_grid_columnWeights) { mStrColumnWeights = a.getString(attr); - } else if (attr == R.styleable.Grid_grid_orientation) { + } else if (attr == R.styleable.Grid_grid_orientation) { mOrientation = a.getInt(attr, 0); } else if (attr == R.styleable.Grid_grid_horizontalGaps) { mHorizontalGaps = a.getDimension(attr, 0); @@ -222,7 +223,7 @@ protected void init(AttributeSet attrs) { } else if (attr == R.styleable.Grid_grid_validateInputs) { // @TODO handle validation mValidateInputs = a.getBoolean(attr, false); - } else if (attr == R.styleable.Grid_grid_useRtl) { + } else if (attr == R.styleable.Grid_grid_useRtl) { // @TODO handle RTL mUseRtl = a.getBoolean(attr, false); } @@ -243,13 +244,13 @@ private void updateActualRowsAndColumns() { if (mRowsSet == 0 || mColumnsSet == 0) { if (mColumnsSet > 0) { mColumns = mColumnsSet; - mRows = (mCount + mColumns -1) / mColumnsSet; // round up - } else if (mRowsSet > 0) { + mRows = (mCount + mColumns - 1) / mColumnsSet; // round up + } else if (mRowsSet > 0) { mRows = mRowsSet; - mColumns= (mCount + mRowsSet -1) / mRowsSet; // round up + mColumns = (mCount + mRowsSet - 1) / mRowsSet; // round up } else { // as close to square as possible favoring more rows - mRows = (int) (1.5 + Math.sqrt(mCount)); - mColumns = (mCount + mRows -1) / mRows; + mRows = (int) (1.5 + Math.sqrt(mCount)); + mColumns = (mCount + mRows - 1) / mRows; } } else { mRows = mRowsSet; @@ -262,18 +263,18 @@ public void onAttachedToWindow() { super.onAttachedToWindow(); mContainer = (ConstraintLayout) getParent(); - mConstraintSet.clone(mContainer); generateGrid(false); } /** * generate the Grid form based on the input attributes + * * @param isUpdate whether to update the existing grid (true) or create a new one (false) * @return true if all the inputs are valid else false */ private boolean generateGrid(boolean isUpdate) { - if (mContainer == null || mConstraintSet == null || mRows < 1 || mColumns < 1) { + if (mContainer == null || mRows < 1 || mColumns < 1) { return false; } @@ -306,8 +307,8 @@ private boolean generateGrid(boolean isUpdate) { } isSuccess &= arrangeWidgets(); - mConstraintSet.applyTo(mContainer); - + mContainer.requestLayout(); + applyLayoutFeatures(); return isSuccess || !mValidateInputs; } @@ -316,13 +317,14 @@ private boolean generateGrid(boolean isUpdate) { */ private void initVariables() { mPositionMatrix = new boolean[mRows][mColumns]; - for (boolean[] row: mPositionMatrix) { + for (boolean[] row : mPositionMatrix) { Arrays.fill(row, true); } } /** * parse the weights/pads in the string format into a float array + * * @param size size of the return array * @param str weights/pads in a string format * @return a float array with weights/pads values @@ -344,36 +346,36 @@ private float[] parseWeights(int size, String str) { return arr; } + private ConstraintLayout.LayoutParams params(View v) { + return (ConstraintLayout.LayoutParams) v.getLayoutParams(); + } + /** * Connect the view to the corresponding viewBoxes based on the input params - * @param viewId the Id of the view - * @param row row position to place the view + * + * @param view the Id of the view + * @param row row position to place the view * @param column column position to place the view */ - private void connectView(int viewId, int row, int column, int rowSpan, int columnSpan) { + private void connectView(View view, int row, int column, int rowSpan, int columnSpan) { + ConstraintLayout.LayoutParams params = params(view); // @TODO handle RTL - // connect Start of the view - mConstraintSet.connect(viewId, ConstraintSet.LEFT, mBoxViewIds[column], ConstraintSet.LEFT); - - // connect Top of the view - mConstraintSet.connect(viewId, ConstraintSet.TOP, mBoxViewIds[row], ConstraintSet.TOP); - - mConstraintSet.connect(viewId, ConstraintSet.RIGHT, - mBoxViewIds[column + columnSpan - 1], ConstraintSet.RIGHT); - - // connect Bottom of the view - mConstraintSet.connect(viewId, ConstraintSet.BOTTOM, - mBoxViewIds[row + rowSpan - 1], ConstraintSet.BOTTOM); + // Connect the 4 sides + params.leftToLeft = mBoxViewIds[column]; + params.topToTop = mBoxViewIds[row]; + params.rightToRight = mBoxViewIds[column + columnSpan - 1]; + params.bottomToBottom = mBoxViewIds[row + rowSpan - 1]; } /** * Arrange the views in the constraint_referenced_ids + * * @return true if all the widgets can be arranged properly else false */ private boolean arrangeWidgets() { int position; - + View[] views = getViews(mContainer); // @TODO handle RTL for (int i = 0; i < mCount; i++) { if (mSpanIds.contains(mIds[i])) { @@ -388,19 +390,21 @@ private boolean arrangeWidgets() { // no more available position. return false; } - connectView(mIds[i], row, col, 1, 1); + + connectView(views[i], row, col, 1, 1); } return true; } /** * Convert a 1D index to a 2D index that has index for row and index for column + * * @param index index in 1D * @return row as its values. */ private int getRowByIndex(int index) { if (mOrientation == 1) { - return index % mRows; + return index % mRows; } else { return index / mColumns; @@ -410,6 +414,7 @@ private int getRowByIndex(int index) { /** * Convert a 1D index to a 2D index that has index for row and index for column + * * @param index index in 1D * @return column as its values. */ @@ -423,10 +428,11 @@ private int getColByIndex(int index) { /** * Get the next available position for widget arrangement. + * * @return int[] -> [row, column] */ private int getNextPosition() { - // int[] position = new int[] {0, 0}; + // int[] position = new int[] {0, 0}; int position = 0; boolean positionFound = false; @@ -435,7 +441,7 @@ private int getNextPosition() { return -1; } - // position = getPositionByIndex(mNextAvailableIndex); + // position = getPositionByIndex(mNextAvailableIndex); position = mNextAvailableIndex; int row = getRowByIndex(mNextAvailableIndex); int col = getColByIndex(mNextAvailableIndex); @@ -451,16 +457,18 @@ private int getNextPosition() { /** * Check if the value of the spans/skips is valid + * * @param str spans/skips in string format * @return true if it is valid else false */ - private boolean isSpansValid(String str) { + private boolean isSpansValid(CharSequence str) { // TODO: check string has a valid format. return true; } /** * Check if the value of the rowWeights or columnsWeights is valid + * * @param str rowWeights/columnsWeights in string format * @return true if it is valid else false */ @@ -476,6 +484,7 @@ private boolean isWeightsValid(String str) { * index - the index of the starting position * row_span - the number of rows to span * col_span- the number of columns to span + * * @param str string format of skips or spans * @return a int matrix that contains skip information. */ @@ -501,10 +510,12 @@ private int[][] parseSpans(String str) { /** * Handle the span use cases + * * @param spansMatrix a int matrix that contains span information * @return true if the input spans is valid else false */ private boolean handleSpans(int[] mId, int[][] spansMatrix) { + View[] views = getViews(mContainer); for (int i = 0; i < spansMatrix.length; i++) { int row = getRowByIndex(spansMatrix[i][0]); int col = getColByIndex(spansMatrix[i][0]); @@ -512,8 +523,10 @@ private boolean handleSpans(int[] mId, int[][] spansMatrix) { spansMatrix[i][1], spansMatrix[i][2])) { return false; } - connectView(mId[i], row, col, - spansMatrix[i][1], spansMatrix[i][2]); + + connectView(views[i], row, col, + spansMatrix[i][1], spansMatrix[i][2]); + mSpanIds.add(mId[i]); } return true; @@ -521,11 +534,12 @@ private boolean handleSpans(int[] mId, int[][] spansMatrix) { /** * Make positions in the grid unavailable based on the skips attr + * * @param skipsMatrix a int matrix that contains skip information * @return true if all the skips are valid else false */ private boolean handleSkips(int[][] skipsMatrix) { - for(int i = 0; i < skipsMatrix.length; i++) { + for (int i = 0; i < skipsMatrix.length; i++) { int row = getRowByIndex(skipsMatrix[i][0]); int col = getColByIndex(skipsMatrix[i][0]); if (!invalidatePositions(row, col, @@ -538,10 +552,11 @@ private boolean handleSkips(int[][] skipsMatrix) { /** * Make the specified positions in the grid unavailable. - * @param startRow the row of the staring position + * + * @param startRow the row of the staring position * @param startColumn the column of the staring position - * @param rowSpan how many rows to span - * @param columnSpan how many columns to span + * @param rowSpan how many rows to span + * @param columnSpan how many columns to span * @return true if we could properly invalidate the positions else false */ private boolean invalidatePositions(int startRow, int startColumn, @@ -561,6 +576,7 @@ private boolean invalidatePositions(int startRow, int startColumn, /** * Visualize the boxViews that are used to constraint widgets. + * * @param canvas canvas to visualize the boxViews */ @Override @@ -571,8 +587,7 @@ public void onDraw(Canvas canvas) { return; } @SuppressLint("DrawAllocation") - Paint paint = new Paint(); // only used in design time - + Paint paint = new Paint(); // used only during design time paint.setColor(Color.RED); paint.setStyle(Paint.Style.STROKE); int myTop = getTop(); @@ -590,45 +605,49 @@ public void onDraw(Canvas canvas) { } /** - * Set chain between boxView horzontally + * Set chain between boxView horizontally */ private void setBoxViewHorizontalChains() { int gridId = getId(); int maxVal = Math.max(mRows, mColumns); - int minVal = Math.min(mRows, mColumns); - float[] columnWeights = parseWeights(mColumns, mStrColumnWeights); + float[] columnWeights = parseWeights(mColumns, mStrColumnWeights); + ConstraintLayout.LayoutParams params = params(mBoxViews[0]); // chain all the views on the longer side (either horizontal or vertical) if (mColumns == 1) { - mConstraintSet.center(mBoxViewIds[0], gridId, ConstraintSet.LEFT, 0, gridId, - ConstraintSet.RIGHT, 0, 0.5f); - return; - } - if (maxVal == mColumns) { - mConstraintSet.createHorizontalChain(gridId, ConstraintSet.LEFT, gridId, - ConstraintSet.RIGHT, mBoxViewIds, columnWeights, - ConstraintSet.CHAIN_SPREAD_INSIDE); - for (int i = 1; i < mBoxViews.length; i++) { - mConstraintSet.setMargin(mBoxViewIds[i], ConstraintSet.LEFT, (int) mHorizontalGaps); - } + params.leftToLeft = gridId; + params.rightToRight = gridId; return; } - // chain partial veriws on the shorter side (either horizontal or vertical) - // add constraints to the parent for the non-chained views - mConstraintSet.createHorizontalChain(gridId, ConstraintSet.LEFT, gridId, - ConstraintSet.RIGHT, Arrays.copyOf(mBoxViewIds, minVal), columnWeights, - ConstraintSet.CHAIN_SPREAD_INSIDE); - for (int i = 1; i < mBoxViews.length; i++) { - if (i < minVal) { - mConstraintSet.setMargin(mBoxViewIds[i], ConstraintSet.LEFT, (int) mHorizontalGaps); + // chains are grid <- box <-> box <-> box -> grid + + for (int i = 0; i < mColumns; i++) { + params = params(mBoxViews[i]); + if (columnWeights != null) { + params.horizontalWeight = columnWeights[i]; + } + if (i > 0) { + params.leftToRight = mBoxViewIds[i - 1]; + } else { + params.leftToLeft = gridId; + } + if (i < mColumns - 1) { + params.rightToLeft = mBoxViewIds[i + 1]; } else { - mConstraintSet.connect(mBoxViewIds[i], ConstraintSet.LEFT, - gridId, ConstraintSet.LEFT); - mConstraintSet.connect(mBoxViewIds[i], ConstraintSet.RIGHT, - gridId, ConstraintSet.RIGHT); + params.rightToRight = gridId; } + if (i > 0) { + params.leftMargin = (int) mHorizontalGaps; + } + } + // excess boxes are connected to grid those sides are not use + // for efficiency they should be connected to parent + for (int i = mColumns; i < maxVal; i++) { + params = params(mBoxViews[i]); + params.leftToLeft = gridId; + params.rightToRight = gridId; } } @@ -638,58 +657,94 @@ private void setBoxViewHorizontalChains() { private void setBoxViewVerticalChains() { int gridId = getId(); int maxVal = Math.max(mRows, mColumns); - int minVal = Math.min(mRows, mColumns); - float[] rowWeights = parseWeights(mRows, mStrRowWeights); + float[] rowWeights = parseWeights(mRows, mStrRowWeights); + ConstraintLayout.LayoutParams params; // chain all the views on the longer side (either horizontal or vertical) if (mRows == 1) { - mConstraintSet.center(mBoxViewIds[0], gridId, ConstraintSet.TOP, 0, gridId, - ConstraintSet.BOTTOM, 0, 0.5f); + params = params(mBoxViews[0]); + params.topToTop = gridId; + params.bottomToBottom = gridId; return; } - if (maxVal == mRows) { - mConstraintSet.createVerticalChain(gridId, ConstraintSet.TOP, gridId, - ConstraintSet.BOTTOM, mBoxViewIds, rowWeights, - ConstraintSet.CHAIN_SPREAD_INSIDE); - for (int i = 1; i < mBoxViews.length; i++) { - mConstraintSet.setMargin(mBoxViewIds[i], ConstraintSet.TOP, (int) mVerticalGaps); + // chains are constrained like this: grid <- box <-> box <-> box -> grid + for (int i = 0; i < mRows; i++) { + params = params(mBoxViews[i]); + if (rowWeights != null) { + params.verticalWeight = rowWeights[i]; } - return; - } - - // chain partial veriws on the shorter side (either horizontal or vertical) - // add constraints to the parent for the non-chained views - mConstraintSet.createVerticalChain(gridId, ConstraintSet.TOP, gridId, - ConstraintSet.BOTTOM, Arrays.copyOf(mBoxViewIds, minVal), rowWeights, - ConstraintSet.CHAIN_SPREAD_INSIDE); - for (int i = 1; i < mBoxViews.length; i++) { - if (i < minVal) { - mConstraintSet.setMargin(mBoxViewIds[i], ConstraintSet.TOP, (int) mVerticalGaps); + if (i > 0) { + params.topToBottom = mBoxViewIds[i - 1]; + } else { + params.topToTop = gridId; + } + if (i < mRows - 1) { + params.bottomToTop = mBoxViewIds[i + 1]; } else { - mConstraintSet.connect(mBoxViewIds[i], ConstraintSet.TOP, - gridId, ConstraintSet.TOP); - mConstraintSet.connect(mBoxViewIds[i], ConstraintSet.BOTTOM, - gridId, ConstraintSet.BOTTOM); + params.bottomToBottom = gridId; } + if (i > 0) { + params.topMargin = (int) mHorizontalGaps; + } + } + + // excess boxes are connected to grid those sides are not use + // for efficiency they should be connected to parent + for (int i = mRows; i < maxVal; i++) { + params = params(mBoxViews[i]); + params.topToTop = gridId; + params.bottomToBottom = gridId; } } + private View makeNewView() { + View v = new View(getContext()); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { + v.setId(View.generateViewId()); + } + v.setVisibility(INVISIBLE); + if (DEBUG_BOXES) { + v.setVisibility(VISIBLE); + v.setBackgroundColor(0xFF880088); + } + ConstraintLayout.LayoutParams params = + new ConstraintLayout.LayoutParams(0, 0); + + mContainer.addView(v, params); + return v; + } + /** * create boxViews for constraining widgets */ private void buildBoxes() { int boxCount = Math.max(mRows, mColumns); - mBoxViews = new View[boxCount]; - mBoxViewIds = new int[boxCount]; - for (int i = 0; i < mBoxViews.length; i++) { - mBoxViews[i] = new View(getContext()); // need to remove old Views - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { - mBoxViews[i].setId(View.generateViewId()); + if (mBoxViews == null) { // no box views build all + mBoxViews = new View[boxCount]; + for (int i = 0; i < mBoxViews.length; i++) { + mBoxViews[i] = makeNewView(); // need to remove old Views } - ConstraintLayout.LayoutParams params = - new ConstraintLayout.LayoutParams(0, 0); + } else { + if (boxCount != mBoxViews.length) { + View[] temp = new View[boxCount]; + for (int i = 0; i < boxCount; i++) { + if (i < mBoxViews.length) { // use old one + temp[i] = mBoxViews[i]; + } else { // make new one + temp[i] = makeNewView(); + } + } + // remove excess + for (int j = boxCount; j < mBoxViews.length; j++) { + View view = mBoxViews[j]; + mContainer.removeView(view); + } + mBoxViews = temp; + } + } - mContainer.addView(mBoxViews[i], params); + mBoxViewIds = new int[boxCount]; + for (int i = 0; i < mBoxViews.length; i++) { mBoxViewIds[i] = mBoxViews[i].getId(); } @@ -699,6 +754,7 @@ private void buildBoxes() { /** * get the value of rows + * * @return the value of rows */ public int getRows() { @@ -707,6 +763,7 @@ public int getRows() { /** * set new rows value and also invoke initVariables and invalidate + * * @param rows new rows value */ public void setRows(int rows) { @@ -728,6 +785,7 @@ public void setRows(int rows) { /** * get the value of columns + * * @return the value of columns */ public int getColumns() { @@ -736,6 +794,7 @@ public int getColumns() { /** * set new columns value and also invoke initVariables and invalidate + * * @param columns new rows value */ public void setColumns(int columns) { @@ -757,6 +816,7 @@ public void setColumns(int columns) { /** * get the value of orientation + * * @return the value of orientation */ public int getOrientation() { @@ -765,6 +825,7 @@ public int getOrientation() { /** * set new orientation value and also invoke invalidate + * * @param orientation new orientation value */ public void setOrientation(int orientation) { @@ -783,6 +844,7 @@ public void setOrientation(int orientation) { /** * get the string value of spans + * * @return the string value of spans */ public String getSpans() { @@ -791,24 +853,26 @@ public String getSpans() { /** * set new spans value and also invoke invalidate + * * @param spans new spans value */ - public void setSpans(String spans) { + public void setSpans(CharSequence spans) { if (!isSpansValid(spans)) { return; } - if (mStrSpans != null && mStrSpans.equals(spans)) { + if (mStrSpans != null && mStrSpans.contentEquals(spans)) { return; } - mStrSpans = spans; + mStrSpans = spans.toString(); generateGrid(true); invalidate(); } /** * get the string value of skips + * * @return the string value of skips */ public String getSkips() { @@ -817,6 +881,7 @@ public String getSkips() { /** * set new skips value and also invoke invalidate + * * @param skips new spans value */ public void setSkips(String skips) { @@ -835,6 +900,7 @@ public void setSkips(String skips) { /** * get the string value of rowWeights + * * @return the string value of rowWeights */ public String getRowWeights() { @@ -843,6 +909,7 @@ public String getRowWeights() { /** * set new rowWeights value and also invoke invalidate + * * @param rowWeights new rowWeights value */ public void setRowWeights(String rowWeights) { @@ -861,6 +928,7 @@ public void setRowWeights(String rowWeights) { /** * get the string value of columnWeights + * * @return the string value of columnWeights */ public String getColumnWeights() { @@ -869,6 +937,7 @@ public String getColumnWeights() { /** * set new columnWeights value and also invoke invalidate + * * @param columnWeights new columnWeights value */ public void setColumnWeights(String columnWeights) { @@ -887,6 +956,7 @@ public void setColumnWeights(String columnWeights) { /** * get the value of horizontalGaps + * * @return the value of horizontalGaps */ public float getHorizontalGaps() { @@ -894,7 +964,8 @@ public float getHorizontalGaps() { } /** - * set new horizontalGaps value and also invoke invalidate + * set new horizontalGaps value and also invoke invalidate + * * @param horizontalGaps new horizontalGaps value */ public void setHorizontalGaps(float horizontalGaps) { @@ -913,6 +984,7 @@ public void setHorizontalGaps(float horizontalGaps) { /** * get the value of verticalGaps + * * @return the value of verticalGaps */ public float getVerticalGaps() { @@ -921,6 +993,7 @@ public float getVerticalGaps() { /** * set new verticalGaps value and also invoke invalidate + * * @param verticalGaps new verticalGaps value */ public void setVerticalGaps(float verticalGaps) { diff --git a/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/motion/utils/ViewTimeCycle.java b/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/motion/utils/ViewTimeCycle.java index f1d0b4d5d..6e9a99d5c 100644 --- a/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/motion/utils/ViewTimeCycle.java +++ b/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/motion/utils/ViewTimeCycle.java @@ -261,8 +261,8 @@ public static class CustomSet extends ViewTimeCycle { SparseArray mConstraintAttributeList; SparseArray mWaveProperties = new SparseArray<>(); float[] mTempValues; - float[] mCache; + @SuppressWarnings("StringSplitter") public CustomSet(String attribute, SparseArray attrList) { mAttributeName = attribute.split(",")[1]; mConstraintAttributeList = attrList; diff --git a/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/motion/widget/KeyAttributes.java b/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/motion/widget/KeyAttributes.java index 7aaa8a778..01f97d78e 100644 --- a/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/motion/widget/KeyAttributes.java +++ b/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/motion/widget/KeyAttributes.java @@ -493,6 +493,7 @@ public Key copy(Key src) { mTranslationY = k.mTranslationY; mTranslationZ = k.mTranslationZ; mProgress = k.mProgress; + mTransitionEasing = k.mTransitionEasing; return this; } diff --git a/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/motion/widget/KeyTimeCycle.java b/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/motion/widget/KeyTimeCycle.java index fb22db41b..30eb36809 100644 --- a/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/motion/widget/KeyTimeCycle.java +++ b/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/motion/widget/KeyTimeCycle.java @@ -379,6 +379,7 @@ public Key copy(Key src) { mTranslationX = k.mTranslationX; mTranslationY = k.mTranslationY; mTranslationZ = k.mTranslationZ; + mCustomWaveShape = k.mCustomWaveShape; return this; } diff --git a/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/motion/widget/MotionScene.java b/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/motion/widget/MotionScene.java index 9c8bd66db..62d335244 100644 --- a/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/motion/widget/MotionScene.java +++ b/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/motion/widget/MotionScene.java @@ -809,19 +809,6 @@ public boolean isEnabled() { return !mDisable; } - /** - * Enable or disable the Transition. If a Transition is disabled it is not eligible - * for automatically switching to. - * - * @param enable - * deprecated This method should be called {@code setEnabled}, so that {@code isEnabled} - * can be accessed as a property from Kotlin. - * Use {@link #setEnabled(boolean)} instead. - */ - private void setEnable(boolean enable) { - setEnabled(enable); - } - /** * enable or disable the Transition. If a Transition is disabled it is not eligible * for automatically switching to. diff --git a/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/utils/widget/ImageFilterView.java b/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/utils/widget/ImageFilterView.java index ebe877f28..12b154a1f 100644 --- a/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/utils/widget/ImageFilterView.java +++ b/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/utils/widget/ImageFilterView.java @@ -144,7 +144,9 @@ private void warmth(float warmth) { float colorR, colorG, colorB; if (centiKelvin > 66) { float tmp = centiKelvin - 60.f; - colorR = (329.698727446f * (float) Math.pow(tmp, -0.1332047592f)); + // colorR = (329.698727446f * (float) Math.pow(tmp, -0.1332047592f)) + // colorG = (288.1221695283f * (float) Math.pow(tmp, 0.0755148492f)) + colorR = (329.69873f * (float) Math.pow(tmp, -0.1332047592f)); colorG = (288.1221695283f * (float) Math.pow(tmp, 0.0755148492f)); } else { @@ -153,8 +155,9 @@ private void warmth(float warmth) { } if (centiKelvin < 66) { if (centiKelvin > 19) { - colorB = (138.5177312231f - * (float) Math.log(centiKelvin - 10) - 305.0447927307f); + // 138.5177312231f * (float) Math.log(centiKelvin - 10) - 305.0447927307f); + colorB = (138.51773f + * (float) Math.log(centiKelvin - 10) - 305.0448f); } else { colorB = 0; } @@ -175,17 +178,20 @@ private void warmth(float warmth) { float colorR, colorG, colorB; if (centiKelvin > 66) { float tmp = centiKelvin - 60.f; - colorR = (329.698727446f * (float) Math.pow(tmp, -0.1332047592f)); - colorG = (288.1221695283f * (float) Math.pow(tmp, 0.0755148492f)); + // colorR = (329.698727446f * (float) Math.pow(tmp, -0.1332047592f)); + // colorG = (288.1221695283f * (float) Math.pow(tmp, 0.0755148492f)); + colorR = (329.69873f * (float) Math.pow(tmp, -0.13320476f)); + colorG = (288.12216f * (float) Math.pow(tmp, 0.075514849f)); } else { - colorG = (99.4708025861f * (float) Math.log(centiKelvin) - 161.1195681661f); + //float of (99.4708025861f * (float) Math.log(centiKelvin) - 161.1195681661f); + colorG = (99.4708f * (float) Math.log(centiKelvin) - 161.11957f); colorR = 255; } if (centiKelvin < 66) { if (centiKelvin > 19) { - colorB = (138.5177312231f - * (float) Math.log(centiKelvin - 10) - 305.0447927307f); + //float of (138.5177312231 * Math.log(centiKelvin - 10) - 305.0447927307); + colorB = (138.51773f * (float) Math.log(centiKelvin - 10) - 305.0448f); } else { colorB = 0; } @@ -482,10 +488,10 @@ private void setMatrix() { ) { return; } - float panX = (Float.isNaN(mPanX)) ? 0 : mPanX; - float panY = (Float.isNaN(mPanY)) ? 0 : mPanY; - float zoom = (Float.isNaN(mZoom)) ? 1 : mZoom; - float rota = (Float.isNaN(mRotate)) ? 0 : mRotate; + float panX = Float.isNaN(mPanX) ? 0 : mPanX; + float panY = Float.isNaN(mPanY) ? 0 : mPanY; + float zoom = Float.isNaN(mZoom) ? 1 : mZoom; + float rota = Float.isNaN(mRotate) ? 0 : mRotate; Matrix imageMatrix = new Matrix(); imageMatrix.reset(); float iw = getDrawable().getIntrinsicWidth(); @@ -660,7 +666,7 @@ public void setCrossfade(float crossfade) { if (!mOverlay) { mLayer.getDrawable(0).setAlpha((int) (255 * (1 - mCrossfade))); } - mLayer.getDrawable(1).setAlpha((int) (255 * (mCrossfade))); + mLayer.getDrawable(1).setAlpha((int) (255 * mCrossfade)); super.setImageDrawable(mLayer); } } diff --git a/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/utils/widget/MotionLabel.java b/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/utils/widget/MotionLabel.java index 6320972a1..a4c708a28 100644 --- a/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/utils/widget/MotionLabel.java +++ b/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/utils/widget/MotionLabel.java @@ -231,14 +231,14 @@ private void setupTexture() { if (iw <= 0) { int w = getWidth(); if (w == 0) { - w = ((Float.isNaN(mTextureWidth)) ? 128 : (int) mTextureWidth); + w = (Float.isNaN(mTextureWidth) ? 128 : (int) mTextureWidth); } iw = w; } if (ih <= 0) { int h = getHeight(); if (h == 0) { - h = ((Float.isNaN(mTextureHeight)) ? 128 : (int) mTextureHeight); + h = (Float.isNaN(mTextureHeight) ? 128 : (int) mTextureHeight); } ih = h; } @@ -326,7 +326,7 @@ private float getHorizontalOffset() { float scale = Float.isNaN(mBaseTextSize) ? 1.0f : mTextSize / mBaseTextSize; float textWidth = scale * mPaint.measureText(mText, 0, mText.length()); - float boxWidth = ((Float.isNaN(mFloatWidth)) ? getMeasuredWidth() : mFloatWidth) + float boxWidth = (Float.isNaN(mFloatWidth) ? getMeasuredWidth() : mFloatWidth) - getPaddingLeft() - getPaddingRight(); return (boxWidth - textWidth) * (1 + mTextPanX) / 2.f; @@ -337,7 +337,7 @@ private float getVerticalOffset() { Paint.FontMetrics fm = mPaint.getFontMetrics(); - float boxHeight = ((Float.isNaN(mFloatHeight)) ? getMeasuredHeight() : mFloatHeight) + float boxHeight = (Float.isNaN(mFloatHeight) ? getMeasuredHeight() : mFloatHeight) - getPaddingTop() - getPaddingBottom(); @@ -429,9 +429,9 @@ public void layout(int l, int t, int r, int b) { float vh = mFloatHeight - mPaddingBottom - mPaddingTop; if (normalScale) { if (tw * vh > th * vw) { // width limited tw/vw > th/vh - mPaint.setTextSize((mPaintTextSize * vw) / (tw)); + mPaint.setTextSize(mPaintTextSize * vw / (tw)); } else { // height limited - mPaint.setTextSize((mPaintTextSize * vh) / (th)); + mPaint.setTextSize(mPaintTextSize * vh / (th)); } } else { scaleText = (tw * vh > th * vw) ? vw / (float) tw : vh / (float) th; @@ -475,9 +475,9 @@ public void layout(float l, float t, float r, float b) { float vw = r - l - mPaddingRight - mPaddingLeft; float vh = b - t - mPaddingBottom - mPaddingTop; if (tw * vh > th * vw) { // width limited tw/vw > th/vh - mPaint.setTextSize((mPaintTextSize * vw) / (tw)); + mPaint.setTextSize(mPaintTextSize * vw / (tw)); } else { // height limited - mPaint.setTextSize((mPaintTextSize * vh) / (th)); + mPaint.setTextSize(mPaintTextSize * vh / (th)); } if (mUseOutline || !Float.isNaN(mBaseTextSize)) { buildShape(Float.isNaN(mBaseTextSize) ? 1.0f : mTextSize / mBaseTextSize); @@ -646,7 +646,7 @@ public Typeface getTypeface() { return mPaint.getTypeface(); } - // @Override + @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthMode = View.MeasureSpec.getMode(widthMeasureSpec); int heightMode = View.MeasureSpec.getMode(heightMeasureSpec); @@ -946,16 +946,16 @@ public void setTextBackgroundRotate(float rotation) { } private void updateShaderMatrix() { - float panX = (Float.isNaN(mBackgroundPanX)) ? 0 : mBackgroundPanX; - float panY = (Float.isNaN(mBackgroundPanY)) ? 0 : mBackgroundPanY; - float zoom = (Float.isNaN(mZoom)) ? 1 : mZoom; - float rota = (Float.isNaN(mRotate)) ? 0 : mRotate; + float panX = Float.isNaN(mBackgroundPanX) ? 0 : mBackgroundPanX; + float panY = Float.isNaN(mBackgroundPanY) ? 0 : mBackgroundPanY; + float zoom = Float.isNaN(mZoom) ? 1 : mZoom; + float rota = Float.isNaN(mRotate) ? 0 : mRotate; mTextShaderMatrix.reset(); float iw = mTextBackgroundBitmap.getWidth(); float ih = mTextBackgroundBitmap.getHeight(); - float sw = (Float.isNaN(mTextureWidth)) ? mFloatWidth : mTextureWidth; - float sh = (Float.isNaN(mTextureHeight)) ? mFloatHeight : mTextureHeight; + float sw = Float.isNaN(mTextureWidth) ? mFloatWidth : mTextureWidth; + float sh = Float.isNaN(mTextureHeight) ? mFloatHeight : mTextureHeight; float scale = zoom * ((iw * sh < ih * sw) ? sw / iw : sh / ih); mTextShaderMatrix.postScale(scale, scale); @@ -967,8 +967,8 @@ private void updateShaderMatrix() { if (!Float.isNaN(mTextureWidth)) { gapx = mTextureWidth / 2; } - float tx = 0.5f * (panX * (gapx) + sw - (scale * iw)); - float ty = 0.5f * (panY * (gapy) + sh - (scale * ih)); + float tx = 0.5f * (panX * gapx + sw - (scale * iw)); + float ty = 0.5f * (panY * gapy + sh - (scale * ih)); mTextShaderMatrix.postTranslate(tx, ty); mTextShaderMatrix.postRotate(rota, sw / 2, sh / 2); diff --git a/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/widget/ConstraintHelper.java b/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/widget/ConstraintHelper.java index a6a481a96..3ff31df30 100644 --- a/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/widget/ConstraintHelper.java +++ b/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/widget/ConstraintHelper.java @@ -96,6 +96,11 @@ public abstract class ConstraintHelper extends View { */ private View[] mViews = null; + /** + * @DoNotShow + */ + protected final static String CHILD_TAG = "CONSTRAINT_LAYOUT_HELPER_CHILD"; + protected HashMap mMap = new HashMap<>(); public ConstraintHelper(Context context) { @@ -702,4 +707,15 @@ public int indexFromId(final int id) { } return index; } + + /** + * hook for helpers to apply parameters in MotionLayout + */ + public void applyHelperParams() { + + } + + public static boolean isChildOfHelper(View v) { + return CHILD_TAG == v.getTag(); + } } diff --git a/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/widget/ConstraintLayout.java b/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/widget/ConstraintLayout.java index dcd962818..9d7ad8d87 100644 --- a/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/widget/ConstraintLayout.java +++ b/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/widget/ConstraintLayout.java @@ -18,7 +18,6 @@ import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; - import static androidx.constraintlayout.widget.ConstraintLayout.LayoutParams.MATCH_CONSTRAINT_SPREAD; import static androidx.constraintlayout.widget.ConstraintLayout.LayoutParams.MATCH_CONSTRAINT_WRAP; import static androidx.constraintlayout.widget.ConstraintLayout.LayoutParams.PARENT_ID; @@ -605,7 +604,7 @@ public class ConstraintLayout extends ViewGroup { * @DoNotShow */ public static final int DESIGN_INFO_ID = 0; - private ConstraintsChangedListener mConstraintsChangedListener; + // private ConstraintsChangedListener mConstraintsChangedListener; private Metrics mMetrics; private static SharedValues sSharedValues = null; @@ -851,7 +850,7 @@ public final void measure(ConstraintWidget widget, || !shouldDoWrap || (shouldDoWrap && otherDimensionStable) || (child instanceof Placeholder) - || (widget.isResolvedVertically()); + || widget.isResolvedVertically(); if (useCurrent) { verticalSpec = MeasureSpec.makeMeasureSpec(widget.getHeight(), MeasureSpec.EXACTLY); @@ -2195,6 +2194,7 @@ protected void dispatchDraw(Canvas canvas) { Object tag = child.getTag(); if (tag != null && tag instanceof String) { String coordinates = (String) tag; + @SuppressWarnings("StringSplitter") String[] split = coordinates.split(","); if (split.length == 4) { int x = Integer.parseInt(split[0]); @@ -2267,7 +2267,7 @@ protected void dispatchDraw(Canvas canvas) { * @param constraintsChangedListener */ public void setOnConstraintsChanged(ConstraintsChangedListener constraintsChangedListener) { - this.mConstraintsChangedListener = constraintsChangedListener; + // this.mConstraintsChangedListener = constraintsChangedListener; if (mConstraintLayoutSpec != null) { mConstraintLayoutSpec.setOnConstraintsChanged(constraintsChangedListener); } @@ -2872,11 +2872,15 @@ public void reset() { /** * Create a LayoutParams base on an existing layout Params * - * @param source the Layout Params to be copied + * @param params the Layout Params to be copied */ - public LayoutParams(LayoutParams source) { - super(source); + public LayoutParams(ViewGroup.LayoutParams params) { + super(params); + if (!(params instanceof LayoutParams)) { + return; + } + LayoutParams source = (LayoutParams) params; /////////////////////////////////////////////////////////////////////////////////////// // Layout margins handling TODO: re-activate in 3.0 /////////////////////////////////////////////////////////////////////////////////////// @@ -3753,10 +3757,6 @@ public LayoutParams(int width, int height) { super(width, height); } - public LayoutParams(ViewGroup.LayoutParams source) { - super(source); - } - /** * {@inheritDoc} */ diff --git a/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/widget/ConstraintSet.java b/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/widget/ConstraintSet.java index 1197d6792..c2d16acea 100644 --- a/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/widget/ConstraintSet.java +++ b/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/widget/ConstraintSet.java @@ -2982,7 +2982,6 @@ public void createVerticalChain(int topId, connect(chainIds[0], TOP, topId, topSide, 0); for (int i = 1; i < chainIds.length; i++) { - int chainId = chainIds[i]; connect(chainIds[i], TOP, chainIds[i - 1], BOTTOM, 0); connect(chainIds[i - 1], BOTTOM, chainIds[i], TOP, 0); if (weights != null) { @@ -3064,7 +3063,6 @@ private void createHorizontalChain(int leftId, get(chainIds[0]).layout.horizontalChainStyle = style; connect(chainIds[0], left, leftId, leftSide, UNSET); for (int i = 1; i < chainIds.length; i++) { - int chainId = chainIds[i]; connect(chainIds[i], left, chainIds[i - 1], right, UNSET); connect(chainIds[i - 1], right, chainIds[i], left, UNSET); if (weights != null) { @@ -4588,7 +4586,7 @@ public void load(Context context, XmlPullParser parser) { case XmlResourceParser.START_TAG: tagName = parser.getName(); if (DEBUG) { - Log.v(TAG, Debug.getLoc() + " view .... tagName=" + tagName); + Log.v(TAG, Debug.getLoc() + " " + document + " tagName=" + tagName); } switch (tagName) { case "Constraint": @@ -4718,12 +4716,12 @@ public static Constraint buildDelta(Context context, XmlPullParser parser) { AttributeSet attrs = Xml.asAttributeSet(parser); Constraint c = new Constraint(); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ConstraintOverride); - populateOverride(context, c, a); + populateOverride(c, a); a.recycle(); return c; } - private static void populateOverride(Context ctx, Constraint c, TypedArray a) { + private static void populateOverride(Constraint c, TypedArray a) { final int count = a.getIndexCount(); TypedValue type; @@ -5355,7 +5353,7 @@ private static void setDeltaValue(Constraint c, int type, boolean value) { private void populateConstraint(Context ctx, Constraint c, TypedArray a, boolean override) { if (override) { - populateOverride(ctx, c, a); + populateOverride(c, a); return; } final int count = a.getIndexCount(); @@ -5852,6 +5850,16 @@ public void setValidateOnParse(boolean validate) { mValidate = validate; } + /** + * If true perform validation checks when parsing ConstraintSets + * This will slow down parsing and should only be used for debugging + * + * @param validate + */ + public boolean isValidateOnParse() { + return mValidate; + } + /** * Dump the contents * @@ -6323,7 +6331,12 @@ void writeLayout() throws IOException { private void writeGuideline(int orientation, int guideBegin, int guideEnd, - float guidePercent) { + float guidePercent) throws IOException { + writeVariable("'orientation'", orientation); + writeVariable("'guideBegin'", guideBegin); + writeVariable("'guideEnd'", guideEnd); + writeVariable("'guidePercent'", guidePercent); + } diff --git a/constraintlayout/core/src/main/java/androidx/constraintlayout/core/ArrayLinkedVariables.java b/constraintlayout/core/src/main/java/androidx/constraintlayout/core/ArrayLinkedVariables.java index 1324dad20..3575eb4db 100644 --- a/constraintlayout/core/src/main/java/androidx/constraintlayout/core/ArrayLinkedVariables.java +++ b/constraintlayout/core/src/main/java/androidx/constraintlayout/core/ArrayLinkedVariables.java @@ -41,7 +41,7 @@ public class ArrayLinkedVariables implements ArrayRow.ArrayRowVariables { private static final boolean DEBUG = false; static final int NONE = -1; - private static final boolean FULL_NEW_CHECK = false; // full validation (debug purposes) + // private static final boolean FULL_NEW_CHECK = false full validation (debug purposes) int mCurrentSize = 0; // current size, accessed by ArrayRow and LinearSystem @@ -123,6 +123,7 @@ public class ArrayLinkedVariables implements ArrayRow.ArrayRowVariables { * @param variable the variable to add in the list * @param value the value of the variable */ + @Override public final void put(SolverVariable variable, float value) { if (value == 0) { remove(variable, true); @@ -232,6 +233,7 @@ public final void put(SolverVariable variable, float value) { * @param variable the variable we want to add * @param value its value */ + @Override public void add(SolverVariable variable, float value, boolean removeFromDefinition) { if (value > -sEpsilon && value < sEpsilon) { return; @@ -375,6 +377,7 @@ public float use(ArrayRow definition, boolean removeFromDefinition) { * @param variable the variable we want to remove * @return the value of the removed variable */ + @Override public final float remove(SolverVariable variable, boolean removeFromDefinition) { if (mCandidate == variable) { mCandidate = null; @@ -416,6 +419,7 @@ public final float remove(SolverVariable variable, boolean removeFromDefinition) /** * Clear the list of variables */ + @Override public final void clear() { int current = mHead; int counter = 0; @@ -440,6 +444,7 @@ public final void clear() { * @param variable the variable we are looking for * @return return true if we found the variable */ + @Override public boolean contains(SolverVariable variable) { if (mHead == NONE) { return false; @@ -495,6 +500,7 @@ boolean hasAtLeastOnePositiveVariable() { /** * Invert the values of all the variables in the list */ + @Override public void invert() { int current = mHead; int counter = 0; @@ -511,6 +517,7 @@ public void invert() { * * @param amount amount to divide by */ + @Override public void divideByAmount(float amount) { int current = mHead; int counter = 0; @@ -525,6 +532,7 @@ public int getHead() { return mHead; } + @Override public int getCurrentSize() { return mCurrentSize; } @@ -586,6 +594,7 @@ SolverVariable getPivotCandidate() { * @param index the index of the variable we want to return * @return the variable found, or null */ + @Override public SolverVariable getVariable(int index) { int current = mHead; int counter = 0; @@ -605,6 +614,7 @@ public SolverVariable getVariable(int index) { * @param index the index of the variable we want to look up * @return the value of the found variable, or 0 if not found */ + @Override public float getVariableValue(int index) { int current = mHead; int counter = 0; @@ -624,6 +634,7 @@ public float getVariableValue(int index) { * @param v the variable we are looking up * @return the value of the found variable, or 0 if not found */ + @Override public final float get(SolverVariable v) { int current = mHead; int counter = 0; @@ -642,6 +653,7 @@ public final float get(SolverVariable v) { * * @return size in bytes */ + @Override public int sizeInBytes() { int size = 0; size += 3 * (mArrayIndices.length * 4); @@ -652,6 +664,7 @@ public int sizeInBytes() { /** * print out the variables and their values */ + @Override public void display() { int count = mCurrentSize; System.out.print("{ "); diff --git a/constraintlayout/core/src/main/java/androidx/constraintlayout/core/LinearSystem.java b/constraintlayout/core/src/main/java/androidx/constraintlayout/core/LinearSystem.java index 4bab6426c..44f470065 100644 --- a/constraintlayout/core/src/main/java/androidx/constraintlayout/core/LinearSystem.java +++ b/constraintlayout/core/src/main/java/androidx/constraintlayout/core/LinearSystem.java @@ -328,13 +328,13 @@ public SolverVariable createExtraVariable() { return variable; } - private void addError(ArrayRow row) { - row.addError(this, SolverVariable.STRENGTH_NONE); - } - - private void addSingleError(ArrayRow row, int sign) { - addSingleError(row, sign, SolverVariable.STRENGTH_NONE); - } +// private void addError(ArrayRow row) +// row.addError(this, SolverVariable.STRENGTH_NONE); +// +// +// private void addSingleError(ArrayRow row, int sign) +// addSingleError(row, sign, SolverVariable.STRENGTH_NONE); +// void addSingleError(ArrayRow row, int sign, int strength) { String prefix = null; @@ -767,7 +767,7 @@ private int optimize(Row goal, boolean b) { System.out.println("\n****************************"); System.out.println("* OPTIMIZATION *"); System.out.println("* mNumColumns: " + mNumColumns); - System.out.println("* GOAL: " + goal); + System.out.println("* GOAL: " + goal + " " + b); System.out.println("****************************\n"); } @@ -1402,11 +1402,11 @@ public void addSynonym(SolverVariable a, SolverVariable b, int margin) { System.out.println("(S) -> " + a + " = " + b + (margin != 0 ? " + " + margin : "")); } if (b.mIsSynonym) { - margin += b.mSynonymDelta; + margin += (int) b.mSynonymDelta; b = mCache.mIndexedVariables[b.mSynonym]; } if (a.mIsSynonym) { - margin -= a.mSynonymDelta; + margin -= (int) a.mSynonymDelta; a = mCache.mIndexedVariables[a.mSynonym]; } else { a.setSynonym(this, b, 0); @@ -1441,11 +1441,11 @@ public ArrayRow addEquality(SolverVariable a, SolverVariable b, int margin, int + " " + getDisplayStrength(strength)); } if (b.mIsSynonym) { - margin += b.mSynonymDelta; + margin += (int) b.mSynonymDelta; b = mCache.mIndexedVariables[b.mSynonym]; } if (a.mIsSynonym) { - margin -= a.mSynonymDelta; + margin -= (int) a.mSynonymDelta; a = mCache.mIndexedVariables[a.mSynonym]; } else { a.setSynonym(this, b, margin); diff --git a/constraintlayout/core/src/main/java/androidx/constraintlayout/core/Metrics.java b/constraintlayout/core/src/main/java/androidx/constraintlayout/core/Metrics.java index 87bc26469..63578c932 100644 --- a/constraintlayout/core/src/main/java/androidx/constraintlayout/core/Metrics.java +++ b/constraintlayout/core/src/main/java/androidx/constraintlayout/core/Metrics.java @@ -68,6 +68,7 @@ public class Metrics { /** * @TODO: add description */ + @Override public String toString() { return "\n*** Metrics ***\n" + "measures: " + measures + "\n" diff --git a/constraintlayout/core/src/main/java/androidx/constraintlayout/core/motion/Motion.java b/constraintlayout/core/src/main/java/androidx/constraintlayout/core/motion/Motion.java index c2921c4d2..f48d72f29 100644 --- a/constraintlayout/core/src/main/java/androidx/constraintlayout/core/motion/Motion.java +++ b/constraintlayout/core/src/main/java/androidx/constraintlayout/core/motion/Motion.java @@ -78,9 +78,9 @@ public class Motion implements TypedValues { private static final boolean DEBUG = false; private static final boolean FAVOR_FIXED_SIZE_VIEWS = false; MotionWidget mView; - int mId; + public String mId; String mConstraintTag; - private int mCurveFitType = UNSET; + private int mCurveFitType = CurveFit.SPLINE; private MotionPaths mStartMotionPath = new MotionPaths(); private MotionPaths mEndMotionPath = new MotionPaths(); @@ -125,7 +125,7 @@ public class Motion implements TypedValues { private float mQuantizeMotionPhase = Float.NaN; private DifferentialInterpolator mQuantizeMotionInterpolator = null; private boolean mNoMovement = false; - + Motion mRelativeMotion; /** * Get the view to pivot around * @@ -237,16 +237,23 @@ public float getFinalHeight() { * * @return the view id of the view this is in polar mode to or -1 if not in polar */ - public int getAnimateRelativeTo() { + public String getAnimateRelativeTo() { return mStartMotionPath.mAnimateRelativeTo; } /** - * @TODO: add description + * set up the motion to be relative to this other motionController */ public void setupRelative(Motion motionController) { - mStartMotionPath.setupRelative(motionController, motionController.mStartMotionPath); - mEndMotionPath.setupRelative(motionController, motionController.mEndMotionPath); + mRelativeMotion = motionController; + } + + private void setupRelative() { + if (mRelativeMotion == null) { + return; + } + mStartMotionPath.setupRelative(mRelativeMotion, mRelativeMotion.mStartMotionPath); + mEndMotionPath.setupRelative(mRelativeMotion, mRelativeMotion.mEndMotionPath); } public float getCenterX() { @@ -673,6 +680,8 @@ public void setup(int parentWidth, HashSet cycleAttributes = new HashSet<>(); // attributes we need to oscillate HashMap interpolation = new HashMap<>(); ArrayList triggerList = null; + + setupRelative(); if (DEBUG) { if (mKeyList == null) { Utils.log(TAG, ">>>>>>>>>>>>>>> mKeyList==null"); @@ -934,6 +943,7 @@ public void setup(int parentWidth, mSpline[i + 1] = CurveFit.get(mCurveFitType, timePoints, splinePoints); } + // Spline for positions mSpline[0] = CurveFit.get(mCurveFitType, timePoint, splineData); // --------------------------- SUPPORT ARC MODE -------------- if (points[0].mPathMotionArc != UNSET) { @@ -1722,7 +1732,10 @@ public boolean setValue(int id, String value) { mQuantizeMotionInterpolator = getInterpolator(SPLINE_STRING, value, 0); return true; } - + if (MotionType.TYPE_ANIMATE_RELATIVE_TO == id) { + mStartMotionPath.mAnimateRelativeTo = value; + return true; + } return false; } @@ -1763,4 +1776,9 @@ public void setStaggerOffset(float staggerOffset) { public float getMotionStagger() { return mMotionStagger; } + + public void setIdString(String stringId) { + mId = stringId; + mStartMotionPath.mId = mId; + } } diff --git a/constraintlayout/core/src/main/java/androidx/constraintlayout/core/motion/MotionPaths.java b/constraintlayout/core/src/main/java/androidx/constraintlayout/core/motion/MotionPaths.java index c4b370539..beade20ac 100644 --- a/constraintlayout/core/src/main/java/androidx/constraintlayout/core/motion/MotionPaths.java +++ b/constraintlayout/core/src/main/java/androidx/constraintlayout/core/motion/MotionPaths.java @@ -47,6 +47,7 @@ public class MotionPaths implements Comparable { public static final int CARTESIAN = MotionKeyPosition.TYPE_CARTESIAN; public static final int SCREEN = MotionKeyPosition.TYPE_SCREEN; static String[] sNames = {"position", "x", "y", "width", "height", "pathRotate"}; + public String mId; Easing mKeyFrameEasing; int mDrawPath = 0; float mTime; @@ -58,7 +59,7 @@ public class MotionPaths implements Comparable { float mPathRotate = Float.NaN; float mProgress = Float.NaN; int mPathMotionArc = UNSET; - int mAnimateRelativeTo = UNSET; + String mAnimateRelativeTo = null; float mRelativeAngle = Float.NaN; Motion mRelativeToController = null; @@ -121,7 +122,7 @@ public MotionPaths(int parentWidth, MotionKeyPosition c, MotionPaths startTimePoint, MotionPaths endTimePoint) { - if (startTimePoint.mAnimateRelativeTo != UNSET) { + if (startTimePoint.mAnimateRelativeTo != null) { initPolar(parentWidth, parentHeight, c, startTimePoint, endTimePoint); return; } @@ -157,6 +158,7 @@ void initPolar(int parentWidth, mHeight = (int) (s.mHeight + scaleY * scaleHeight); float startfactor = 1 - position; float endfactor = position; + switch (c.mPositionType) { case MotionKeyPosition.TYPE_SCREEN: this.mX = Float.isNaN(c.mPercentX) ? (position * (e.mX - s.mX) + s.mX) @@ -198,7 +200,6 @@ public void setupRelative(Motion mc, MotionPaths relative) { mY = (float) (Math.atan2(dy, dx) + Math.PI / 2); } else { mY = (float) Math.toRadians(mRelativeAngle); - } } @@ -926,7 +927,10 @@ public void applyParameters(MotionWidget c) { point.mDrawPath = c.mMotion.mDrawPath; point.mAnimateCircleAngleTo = c.mMotion.mAnimateCircleAngleTo; point.mProgress = c.mPropertySet.mProgress; - point.mRelativeAngle = 0; // c.layout.circleAngle; + if (c.mWidgetFrame != null && c.mWidgetFrame.widget != null) { + point.mRelativeAngle = c.mWidgetFrame.widget.mCircleConstraintAngle; + } + Set at = c.getCustomAttributeNames(); for (String s : at) { CustomVariable attr = c.getCustomAttribute(s); diff --git a/constraintlayout/core/src/main/java/androidx/constraintlayout/core/motion/MotionWidget.java b/constraintlayout/core/src/main/java/androidx/constraintlayout/core/motion/MotionWidget.java index 1cdd9072a..03d23a965 100644 --- a/constraintlayout/core/src/main/java/androidx/constraintlayout/core/motion/MotionWidget.java +++ b/constraintlayout/core/src/main/java/androidx/constraintlayout/core/motion/MotionWidget.java @@ -57,7 +57,7 @@ public class MotionWidget implements TypedValues { * @DoNotShow */ public static class Motion { - public int mAnimateRelativeTo = UNSET; + public String mAnimateRelativeTo = null; public int mAnimateCircleAngleTo = 0; public String mTransitionEasing = null; public int mPathMotionArc = UNSET; @@ -167,6 +167,10 @@ public boolean setValue(int id, float value) { @Override public boolean setValue(int id, String value) { + if (id == MotionType.TYPE_ANIMATE_RELATIVE_TO) { + mMotion.mAnimateRelativeTo = value; + return true; + } return setValueMotion(id, value); } @@ -180,9 +184,6 @@ public boolean setValue(int id, boolean value) { */ public boolean setValueMotion(int id, int value) { switch (id) { - case MotionType.TYPE_ANIMATE_RELATIVE_TO: - mMotion.mAnimateRelativeTo = value; - break; case MotionType.TYPE_ANIMATE_CIRCLEANGLE_TO: mMotion.mAnimateCircleAngleTo = value; break; diff --git a/constraintlayout/core/src/main/java/androidx/constraintlayout/core/state/ConstraintReference.java b/constraintlayout/core/src/main/java/androidx/constraintlayout/core/state/ConstraintReference.java index f6117ff38..7a03c6a28 100644 --- a/constraintlayout/core/src/main/java/androidx/constraintlayout/core/state/ConstraintReference.java +++ b/constraintlayout/core/src/main/java/androidx/constraintlayout/core/state/ConstraintReference.java @@ -207,6 +207,9 @@ public ArrayList getErrors() { return mErrors; } + @Override + public String getMessage() { return toString(); } + @Override public String toString() { return "IncorrectConstraintException: " + mErrors.toString(); diff --git a/constraintlayout/core/src/main/java/androidx/constraintlayout/core/state/Transition.java b/constraintlayout/core/src/main/java/androidx/constraintlayout/core/state/Transition.java index c66bc1f3c..42abed015 100644 --- a/constraintlayout/core/src/main/java/androidx/constraintlayout/core/state/Transition.java +++ b/constraintlayout/core/src/main/java/androidx/constraintlayout/core/state/Transition.java @@ -705,16 +705,26 @@ public void addCustomColor(int state, String widgetId, String property, int colo } /** - * @TODO: add description + * Update container of parameters for the state + * @param container contains all the widget parameters + * @param state starting or ending */ public void updateFrom(ConstraintWidgetContainer container, int state) { final ArrayList children = container.getChildren(); final int count = children.size(); + WidgetState[] states = new WidgetState[count]; + for (int i = 0; i < count; i++) { ConstraintWidget child = children.get(i); WidgetState widgetState = getWidgetState(child.stringId, null, state); + states[i] = widgetState; widgetState.update(child, state); + String id = widgetState.getPathRelativeId(); + if (id != null) { + widgetState.setPathRelative(getWidgetState(id, null, state)); + } } + calcStagger(); } @@ -844,6 +854,7 @@ static class WidgetState { WidgetFrame mEnd; WidgetFrame mInterpolated; Motion mMotionControl; + boolean mNeedSetup = true; MotionWidget mMotionWidgetStart; MotionWidget mMotionWidgetEnd; MotionWidget mMotionWidgetInterpolated; @@ -886,13 +897,23 @@ public void update(ConstraintWidget child, int state) { mStart.update(child); mMotionWidgetStart.updateMotion(mMotionWidgetStart); mMotionControl.setStart(mMotionWidgetStart); + mNeedSetup = true; } else if (state == END) { mEnd.update(child); mMotionControl.setEnd(mMotionWidgetEnd); + mNeedSetup = true; } mParentWidth = -1; } + /** + * Return the id of the widget to animate relative to + * @return id of widget or null + */ + String getPathRelativeId() { + return mMotionControl.getAnimateRelativeTo(); + } + public WidgetFrame getFrame(int type) { if (type == START) { return mStart; @@ -909,14 +930,20 @@ public void interpolate(int parentWidth, // TODO only update if parentHeight != mParentHeight || parentWidth != mParentWidth) { mParentHeight = parentHeight; mParentWidth = parentWidth; - mMotionControl.setup(parentWidth, parentHeight, 1, System.nanoTime()); - + if (mNeedSetup) { + mMotionControl.setup(parentWidth, parentHeight, 1, System.nanoTime()); + mNeedSetup = false; + } WidgetFrame.interpolate(parentWidth, parentHeight, mInterpolated, mStart, mEnd, transition, progress); mInterpolated.interpolatedPos = progress; mMotionControl.interpolate(mMotionWidgetInterpolated, progress, System.nanoTime(), mKeyCache); } + + public void setPathRelative(WidgetState widgetState) { + mMotionControl.setupRelative( widgetState.mMotionControl); + } } static class KeyPosition { diff --git a/constraintlayout/core/src/main/java/androidx/constraintlayout/core/state/TransitionParser.java b/constraintlayout/core/src/main/java/androidx/constraintlayout/core/state/TransitionParser.java index 6fc562c97..6c960889c 100644 --- a/constraintlayout/core/src/main/java/androidx/constraintlayout/core/state/TransitionParser.java +++ b/constraintlayout/core/src/main/java/androidx/constraintlayout/core/state/TransitionParser.java @@ -18,6 +18,7 @@ import androidx.constraintlayout.core.motion.utils.TypedBundle; import androidx.constraintlayout.core.motion.utils.TypedValues; +import androidx.constraintlayout.core.motion.utils.Utils; import androidx.constraintlayout.core.parser.CLArray; import androidx.constraintlayout.core.parser.CLContainer; import androidx.constraintlayout.core.parser.CLElement; @@ -133,7 +134,7 @@ private static int map(String val, String... types) { private static void map(TypedBundle bundle, int type, String val, String... types) { for (int i = 0; i < types.length; i++) { if (types[i].equals(val)) { - bundle.add(TypedValues.PositionType.TYPE_PATH_MOTION_ARC, i); + bundle.add(type, i); } } } diff --git a/constraintlayout/core/src/main/java/androidx/constraintlayout/core/state/WidgetFrame.java b/constraintlayout/core/src/main/java/androidx/constraintlayout/core/state/WidgetFrame.java index 62628c9bb..9cab2aa82 100644 --- a/constraintlayout/core/src/main/java/androidx/constraintlayout/core/state/WidgetFrame.java +++ b/constraintlayout/core/src/main/java/androidx/constraintlayout/core/state/WidgetFrame.java @@ -163,8 +163,8 @@ public static void interpolate(int parentWidth, if (start.visibility == ConstraintWidget.GONE) { // On visibility gone, keep the same size to do an alpha to zero - startX -= endWidth / 2f; - startY -= endHeight / 2f; + startX -= (int) (endWidth / 2f); + startY -= (int) (endHeight / 2f); startWidth = endWidth; startHeight = endHeight; if (Float.isNaN(startAlpha)) { @@ -175,8 +175,8 @@ public static void interpolate(int parentWidth, if (end.visibility == ConstraintWidget.GONE) { // On visibility gone, keep the same size to do an alpha to zero - endX -= startWidth / 2f; - endY -= startHeight / 2f; + endX -= (int) (startWidth / 2f); + endY -= (int) (startHeight / 2f); endWidth = startWidth; endHeight = startHeight; if (Float.isNaN(endAlpha)) { @@ -510,11 +510,11 @@ void parseCustom(CLElement custom) throws CLParsingException { String vStr = v.content(); if (vStr.matches("#[0-9a-fA-F]+")) { int color = Integer.parseInt(vStr.substring(1), 16); - setCustomAttribute(k.content(), TypedValues.Custom.TYPE_COLOR, color); + setCustomAttribute(name, TypedValues.Custom.TYPE_COLOR, color); } else if (v instanceof CLNumber) { - setCustomAttribute(k.content(), TypedValues.Custom.TYPE_FLOAT, v.getFloat()); + setCustomAttribute(name, TypedValues.Custom.TYPE_FLOAT, v.getFloat()); } else { - setCustomAttribute(k.content(), TypedValues.Custom.TYPE_STRING, vStr); + setCustomAttribute(name, TypedValues.Custom.TYPE_STRING, vStr); } } diff --git a/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/ConstraintWidget.java b/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/ConstraintWidget.java index 52fb00484..f08f5faea 100644 --- a/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/ConstraintWidget.java +++ b/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/ConstraintWidget.java @@ -23,6 +23,7 @@ import androidx.constraintlayout.core.Cache; import androidx.constraintlayout.core.LinearSystem; import androidx.constraintlayout.core.SolverVariable; +import androidx.constraintlayout.core.motion.utils.Utils; import androidx.constraintlayout.core.state.WidgetFrame; import androidx.constraintlayout.core.widgets.analyzer.ChainRun; import androidx.constraintlayout.core.widgets.analyzer.HorizontalWidgetRun; @@ -361,7 +362,7 @@ public boolean hasResolvedTargets(int orientation, int size) { float mResolvedDimensionRatio = 1.0f; private int[] mMaxDimension = {Integer.MAX_VALUE, Integer.MAX_VALUE}; - private float mCircleConstraintAngle = 0; + public float mCircleConstraintAngle = Float.NaN; private boolean mHasBaseline = false; private boolean mInPlaceholder; @@ -602,7 +603,7 @@ public void reset() { mCenterY.reset(); mCenter.reset(); mParent = null; - mCircleConstraintAngle = 0; + mCircleConstraintAngle = Float.NaN; mWidth = 0; mHeight = 0; mDimensionRatio = 0; @@ -676,7 +677,7 @@ private void serializeAnchor(StringBuilder ret, String side, ConstraintAnchor a) } private void serializeCircle(StringBuilder ret, ConstraintAnchor a, float angle) { - if (a.mTarget == null) { + if (a.mTarget == null || Float.isNaN(angle)) { return; } @@ -739,11 +740,17 @@ private void serializeSize(StringBuilder ret, String type, int size, serializeAttribute(ret, "matchMin", matchConstraintMin, 0); serializeAttribute(ret, "matchDef", matchConstraintDefault, MATCH_CONSTRAINT_SPREAD); serializeAttribute(ret, "matchPercent", matchConstraintDefault, 1); + serializeAttribute(ret, "matchConstraintPercent", matchConstraintPercent, 1); + serializeAttribute(ret, "weight", weight, 1); + serializeAttribute(ret, "override", override, 1); + ret.append("},\n"); } /** - * @TODO: add description + * Serialize the anchors for JSON5 output + * @param ret StringBuilder to be populated + * @return the same string builder to alow chaining */ public StringBuilder serialize(StringBuilder ret) { ret.append("{\n"); @@ -1084,12 +1091,12 @@ public void setDebugSolverName(LinearSystem system, String name) { * @DoNotShow */ public void createObjectVariables(LinearSystem system) { - SolverVariable left = system.createObjectVariable(mLeft); - SolverVariable top = system.createObjectVariable(mTop); - SolverVariable right = system.createObjectVariable(mRight); - SolverVariable bottom = system.createObjectVariable(mBottom); + system.createObjectVariable(mLeft); + system.createObjectVariable(mTop); + system.createObjectVariable(mRight); + system.createObjectVariable(mBottom); if (mBaselineDistance > 0) { - SolverVariable baseline = system.createObjectVariable(mBaseline); + system.createObjectVariable(mBaseline); } } @@ -3583,6 +3590,8 @@ public void copy(ConstraintWidget src, HashMap 0; - if (child.isInHorizontalChain() && (ratio)) { + if (child.isInHorizontalChain() && ratio) { optimize = false; break; } - if (child.isInVerticalChain() && (ratio)) { + if (child.isInVerticalChain() && ratio) { optimize = false; break; } diff --git a/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/analyzer/ChainRun.java b/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/analyzer/ChainRun.java index f7c1a1a42..3d1ee982c 100644 --- a/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/analyzer/ChainRun.java +++ b/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/analyzer/ChainRun.java @@ -65,6 +65,7 @@ boolean supportsWrapComputation() { /** * @TODO: add description */ + @Override public long getWrapDimension() { final int count = mWidgets.size(); long wrapDimension = 0; @@ -491,6 +492,7 @@ public void update(Dependency dependency) { /** * @TODO: add description */ + @Override public void applyToWidget() { for (int i = 0; i < mWidgets.size(); i++) { WidgetRun run = mWidgets.get(i); diff --git a/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/analyzer/DependencyGraph.java b/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/analyzer/DependencyGraph.java index 5e4622c16..03bd3f4f5 100644 --- a/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/analyzer/DependencyGraph.java +++ b/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/analyzer/DependencyGraph.java @@ -45,6 +45,7 @@ public class DependencyGraph { private boolean mNeedRedoMeasures = true; private ConstraintWidgetContainer mContainer; private ArrayList mRuns = new ArrayList<>(); + private static final boolean DEBUG = false; // TODO: Unused, should we delete? private ArrayList mRunGroups = new ArrayList<>(); @@ -731,8 +732,9 @@ public void buildGraph(ArrayList runs) { } run.apply(); } - -// displayGraph(); + if (DEBUG) { + displayGraph(); + } } @@ -988,7 +990,7 @@ private String generateDisplayGraph(WidgetRun root, String content) { StringBuilder sb = new StringBuilder(content); if (!(root instanceof HelperReferences) && start.mDependencies.isEmpty() - && end.mDependencies.isEmpty() & start.mTargets.isEmpty() + && end.mDependencies.isEmpty() && start.mTargets.isEmpty() && end.mTargets.isEmpty()) { return content; } diff --git a/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/analyzer/DependencyNode.java b/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/analyzer/DependencyNode.java index 488951d7c..9a2d63c6a 100644 --- a/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/analyzer/DependencyNode.java +++ b/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/analyzer/DependencyNode.java @@ -69,6 +69,7 @@ public void resolve(int value) { /** * @TODO: add description */ + @Override public void update(Dependency node) { for (DependencyNode target : mTargets) { if (!target.resolved) { diff --git a/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/analyzer/DimensionDependency.java b/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/analyzer/DimensionDependency.java index 979b875c3..59669938b 100644 --- a/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/analyzer/DimensionDependency.java +++ b/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/analyzer/DimensionDependency.java @@ -29,6 +29,7 @@ class DimensionDependency extends DependencyNode { } } + @Override public void resolve(int value) { if (resolved) { return; diff --git a/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/analyzer/HorizontalWidgetRun.java b/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/analyzer/HorizontalWidgetRun.java index 570f9ae17..c01424ecf 100644 --- a/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/analyzer/HorizontalWidgetRun.java +++ b/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/analyzer/HorizontalWidgetRun.java @@ -609,6 +609,7 @@ public void update(Dependency dependency) { /** * @TODO: add description */ + @Override public void applyToWidget() { if (start.resolved) { mWidget.setX(start.value); diff --git a/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/analyzer/VerticalWidgetRun.java b/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/analyzer/VerticalWidgetRun.java index 299bb9628..29536a5ca 100644 --- a/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/analyzer/VerticalWidgetRun.java +++ b/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/analyzer/VerticalWidgetRun.java @@ -478,6 +478,7 @@ void apply() { /** * @TODO: add description */ + @Override public void applyToWidget() { if (start.resolved) { mWidget.setY(start.value); diff --git a/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/analyzer/WidgetGroup.java b/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/analyzer/WidgetGroup.java index df9e98b94..34dd23fec 100644 --- a/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/analyzer/WidgetGroup.java +++ b/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/analyzer/WidgetGroup.java @@ -100,6 +100,8 @@ public void moveTo(int orientation, WidgetGroup widgetGroup) { if (DEBUG) { System.out.println("Move all widgets (" + this + ") from " + mId + " to " + widgetGroup.getId() + "(" + widgetGroup + ")"); + System.out.println("" + + "do not call "+ measureWrap( orientation, new ConstraintWidget())); } for (ConstraintWidget widget : mWidgets) { widgetGroup.add(widget); diff --git a/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/analyzer/WidgetRun.java b/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/analyzer/WidgetRun.java index 6abaa39f4..b5a224d2d 100644 --- a/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/analyzer/WidgetRun.java +++ b/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/analyzer/WidgetRun.java @@ -260,6 +260,7 @@ protected void updateRunEnd(Dependency dependency) { /** * @TODO: add description */ + @Override public void update(Dependency dependency) { } diff --git a/projects/ComposeConstraintLayout/app/src/main/java/com/example/constraintlayout/ConstraintMotionProps.kt b/projects/ComposeConstraintLayout/app/src/main/java/com/example/constraintlayout/ConstraintMotionProps.kt index 8e0dc2ed4..fa3ce75cf 100644 --- a/projects/ComposeConstraintLayout/app/src/main/java/com/example/constraintlayout/ConstraintMotionProps.kt +++ b/projects/ComposeConstraintLayout/app/src/main/java/com/example/constraintlayout/ConstraintMotionProps.kt @@ -742,7 +742,7 @@ fun MotionOrbit1() { box1: { width: 50, height: 50, bottom: ['parent', 'bottom', 10], - start: ['parent', 'start', 10], + start: ['parent', 'start', 80], }, title: { top: ['parent', 'top', 10], @@ -754,7 +754,6 @@ fun MotionOrbit1() { bottom: ['parent', 'bottom', 10], start: ['parent', 'start', 10], motion: { - pathArc : 'startHorizontal', relativeTo: 'box1' } } @@ -763,7 +762,7 @@ fun MotionOrbit1() { box1: { width: 50, height: 50, top: ['parent', 'top', 60], - end: ['parent', 'end', 60], + end: ['parent', 'end', 80], }, title: { top: ['parent', 'top', 10], @@ -820,3 +819,103 @@ fun MotionOrbit1() { } } } + + +@Preview +@Composable +fun MotionOrbit2() { + + var scene = + """ + { + ConstraintSets: { + start: { + box1: { + width: 50, height: 50, + bottom: ['parent', 'bottom', 10], + start: ['parent', 'start', 80], + }, + title: { + top: ['parent', 'top', 10], + start: ['parent', 'start', 10], + end: ['parent', 'end', 10], + }, + box2: { + width: 50, height: 50, + circular: ['box1',90, 70], + motion: { + relativeTo: 'box1' + } + } + }, + end: { + box1: { + width: 50, height: 50, + top: ['parent', 'top', 60], + end: ['parent', 'end', 80], + }, + title: { + top: ['parent', 'top', 10], + start: ['parent', 'start', 10], + end: ['parent', 'end', 10], + }, + box2: { + width: 50, height: 50, + circular: ['box1', 1800, 70], + } + } + }, + Transitions: { + default: { + from: 'start', + to: 'end', + KeyFrames: { + KeyPositions: [ + { + target: ['box1'], + type: 'deltaRelative', + frames: [50], + percentX: [ 0.7], + percentY: [ 0.5] + } + ] + }, + onSwipe: { + anchor: 'box1', + maxVelocity: 4.2, + maxAccel: 3, + direction: 'end', + side: 'start', + mode: 'velocity' + } + } + } + } + """.trimIndent() + + Column { + MotionLayout( + modifier = Modifier + .fillMaxSize() + .background(Color.LightGray), + motionScene = MotionScene(content = scene), + debug= EnumSet.of(MotionLayoutDebugFlags.SHOW_ALL), + ) { + Text(text = " Orbit the red ", + modifier = Modifier + .layoutId("title") + .background(Color.Gray)) + Box( + modifier = Modifier + .background(Color.Red) + .layoutId("box1") + ) + Box( + modifier = Modifier + .background(Color.Green) + .layoutId("box2") + ) + } + } +} + diff --git a/projects/ComposeConstraintLayout/app/src/main/java/com/example/constraintlayout/MainActivity.kt b/projects/ComposeConstraintLayout/app/src/main/java/com/example/constraintlayout/MainActivity.kt index 19cc73697..b0781d3a7 100644 --- a/projects/ComposeConstraintLayout/app/src/main/java/com/example/constraintlayout/MainActivity.kt +++ b/projects/ComposeConstraintLayout/app/src/main/java/com/example/constraintlayout/MainActivity.kt @@ -37,7 +37,7 @@ import com.google.accompanist.coil.rememberCoilPainter class MainActivity : AppCompatActivity() { private var mFrameLayout: FrameLayout? = null private var composeNum = 0 - private val START_NUMBER = 48 + private val START_NUMBER = 58 private var demos:ArrayList = ArrayList() var map = HashMap(); val linkServer = LinkServer() @@ -162,6 +162,8 @@ class MainActivity : AppCompatActivity() { demos.add(object : CompFunc { @Composable override fun Run() { MotionQuantize2() } }) demos.add(object : CompFunc { @Composable override fun Run() { MotionStagger1() } }) demos.add(object : CompFunc { @Composable override fun Run() { MotionStagger2() } }) + demos.add(object : CompFunc { @Composable override fun Run() { MotionOrbit1() } }) + demos.add(object : CompFunc { @Composable override fun Run() { MotionOrbit2() } }) demos.add(object : CompFunc { @Composable override fun Run() { Example () } }) demos.add(object : CompFunc { @Composable override fun Run() { RowColExample () } })