VirtualLayout.java
/*
* Copyright (C) 2019 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.core.widgets;
import androidx.constraintlayout.core.widgets.analyzer.BasicMeasure;
import java.util.HashSet;
/**
* @suppress
*
* Base class for Virtual layouts
*
*/
public class VirtualLayout extends HelperWidget {
private int mPaddingTop = 0;
private int mPaddingBottom = 0;
private int mPaddingLeft = 0;
private int mPaddingRight = 0;
private int mPaddingStart =0;
private int mPaddingEnd = 0;
private int mResolvedPaddingLeft = 0;
private int mResolvedPaddingRight = 0;
private boolean mNeedsCallFromSolver = false;
private int mMeasuredWidth = 0;
private int mMeasuredHeight = 0;
protected BasicMeasure.Measure mMeasure = new BasicMeasure.Measure();
/////////////////////////////////////////////////////////////////////////////////////////////
// Accessors
/////////////////////////////////////////////////////////////////////////////////////////////
public void setPadding(int value) {
mPaddingLeft = value;
mPaddingTop = value;
mPaddingRight = value;
mPaddingBottom = value;
mPaddingStart = value;
mPaddingEnd = value;
}
public void setPaddingStart(int value) {
mPaddingStart = value;
mResolvedPaddingLeft = value;
mResolvedPaddingRight = value;
}
public void setPaddingEnd(int value) {
mPaddingEnd = value;
}
public void setPaddingLeft(int value) {
mPaddingLeft = value;
mResolvedPaddingLeft = value;
}
public void applyRtl(boolean isRtl) {
if (mPaddingStart > 0 || mPaddingEnd > 0) {
if (isRtl) {
mResolvedPaddingLeft = mPaddingEnd;
mResolvedPaddingRight = mPaddingStart;
} else {
mResolvedPaddingLeft = mPaddingStart;
mResolvedPaddingRight = mPaddingEnd;
}
}
}
public void setPaddingTop(int value) {
mPaddingTop = value;
}
public void setPaddingRight(int value) {
mPaddingRight = value;
mResolvedPaddingRight = value;
}
public void setPaddingBottom(int value) {
mPaddingBottom = value;
}
public int getPaddingTop() { return mPaddingTop; }
public int getPaddingBottom() { return mPaddingBottom; }
public int getPaddingLeft() { return mResolvedPaddingLeft; }
public int getPaddingRight() { return mResolvedPaddingRight; }
/////////////////////////////////////////////////////////////////////////////////////////////
// Solver callback
/////////////////////////////////////////////////////////////////////////////////////////////
protected void needsCallbackFromSolver(boolean value) {
mNeedsCallFromSolver = value;
}
public boolean needSolverPass() {
return mNeedsCallFromSolver;
}
/////////////////////////////////////////////////////////////////////////////////////////////
// Measure
/////////////////////////////////////////////////////////////////////////////////////////////
public void measure(int widthMode, int widthSize, int heightMode, int heightSize) {
// nothing
}
@Override
public void updateConstraints(ConstraintWidgetContainer container) {
captureWidgets();
}
public void captureWidgets() {
for (int i = 0; i < mWidgetsCount; i++) {
ConstraintWidget widget = mWidgets[i];
if (widget != null) {
widget.setInVirtualLayout(true);
}
}
}
public int getMeasuredWidth() {
return mMeasuredWidth;
}
public int getMeasuredHeight() {
return mMeasuredHeight;
}
public void setMeasure(int width, int height) {
mMeasuredWidth = width;
mMeasuredHeight = height;
}
protected boolean measureChildren() {
BasicMeasure.Measurer measurer = null;
if (mParent != null) {
measurer = ((ConstraintWidgetContainer) mParent).getMeasurer();
}
if (measurer == null) {
return false;
}
for (int i = 0; i < mWidgetsCount; i++) {
ConstraintWidget widget = mWidgets[i];
if (widget == null) {
continue;
}
if (widget instanceof Guideline) {
continue;
}
DimensionBehaviour widthBehavior = widget.getDimensionBehaviour(HORIZONTAL);
DimensionBehaviour heightBehavior = widget.getDimensionBehaviour(VERTICAL);
boolean skip = widthBehavior == DimensionBehaviour.MATCH_CONSTRAINT
&& widget.mMatchConstraintDefaultWidth != MATCH_CONSTRAINT_WRAP
&& heightBehavior == DimensionBehaviour.MATCH_CONSTRAINT
&& widget.mMatchConstraintDefaultHeight != MATCH_CONSTRAINT_WRAP;
if (skip) {
// we don't need to measure here as the dimension of the widget
// will be completely computed by the solver.
continue;
}
if (widthBehavior == DimensionBehaviour.MATCH_CONSTRAINT) {
widthBehavior = DimensionBehaviour.WRAP_CONTENT;
}
if (heightBehavior == DimensionBehaviour.MATCH_CONSTRAINT) {
heightBehavior = DimensionBehaviour.WRAP_CONTENT;
}
mMeasure.horizontalBehavior = widthBehavior;
mMeasure.verticalBehavior = heightBehavior;
mMeasure.horizontalDimension = widget.getWidth();
mMeasure.verticalDimension = widget.getHeight();
measurer.measure(widget, mMeasure);
widget.setWidth(mMeasure.measuredWidth);
widget.setHeight(mMeasure.measuredHeight);
widget.setBaselineDistance(mMeasure.measuredBaseline);
}
return true;
}
BasicMeasure.Measurer mMeasurer = null;
protected void measure(ConstraintWidget widget,
ConstraintWidget.DimensionBehaviour horizontalBehavior, int horizontalDimension,
ConstraintWidget.DimensionBehaviour verticalBehavior, int verticalDimension) {
while (mMeasurer == null && getParent() != null) {
ConstraintWidgetContainer parent = (ConstraintWidgetContainer) getParent();
mMeasurer = parent.getMeasurer();
}
mMeasure.horizontalBehavior = horizontalBehavior;
mMeasure.verticalBehavior = verticalBehavior;
mMeasure.horizontalDimension = horizontalDimension;
mMeasure.verticalDimension = verticalDimension;
mMeasurer.measure(widget, mMeasure);
widget.setWidth(mMeasure.measuredWidth);
widget.setHeight(mMeasure.measuredHeight);
widget.setHasBaseline(mMeasure.measuredHasBaseline);
widget.setBaselineDistance(mMeasure.measuredBaseline);
}
public boolean contains(HashSet<ConstraintWidget> widgets) {
for (int i = 0; i < mWidgetsCount; i++) {
ConstraintWidget widget = mWidgets[i];
if (widgets.contains(widget)) {
return true;
}
}
return false;
}
}