public class

Barrier

extends HelperWidget

 java.lang.Object

androidx.constraintlayout.core.widgets.ConstraintWidget

androidx.constraintlayout.core.widgets.HelperWidget

↳androidx.constraintlayout.core.widgets.Barrier

Gradle dependencies

compile group: 'androidx.constraintlayout', name: 'constraintlayout-core', version: '1.1.0-alpha01'

  • groupId: androidx.constraintlayout
  • artifactId: constraintlayout-core
  • version: 1.1.0-alpha01

Artifact androidx.constraintlayout:constraintlayout-core:1.1.0-alpha01 it located at Google repository (https://maven.google.com/)

Overview

A Barrier takes multiple widgets

Summary

Fields
public static final intBOTTOM

public static final intLEFT

public static final intRIGHT

public static final intTOP

from HelperWidgetmWidgets[], mWidgetsCount
from ConstraintWidgetANCHOR_BASELINE, ANCHOR_BOTTOM, ANCHOR_LEFT, ANCHOR_RIGHT, ANCHOR_TOP, BOTH, CHAIN_PACKED, CHAIN_SPREAD, CHAIN_SPREAD_INSIDE, DEFAULT_BIAS, DIRECT, frame, GONE, HORIZONTAL, horizontalChainRun, horizontalGroup, INVISIBLE, isTerminalWidget[], mAnchors, MATCH_CONSTRAINT_PERCENT, MATCH_CONSTRAINT_RATIO, MATCH_CONSTRAINT_RATIO_RESOLVED, MATCH_CONSTRAINT_SPREAD, MATCH_CONSTRAINT_WRAP, mBaseline, mBottom, mCenter, mDimensionRatio, mDimensionRatioSide, measured, mHorizontalResolution, mHorizontalRun, mIsHeightWrapContent, mIsWidthWrapContent, mLeft, mListAnchors[], mListDimensionBehaviors[], mListNextMatchConstraintsWidget[], mMatchConstraintDefaultHeight, mMatchConstraintDefaultWidth, mMatchConstraintMaxHeight, mMatchConstraintMaxWidth, mMatchConstraintMinHeight, mMatchConstraintMinWidth, mMatchConstraintPercentHeight, mMatchConstraintPercentWidth, mMinHeight, mMinWidth, mNextChainWidget[], mOffsetX, mOffsetY, mParent, mResolvedMatchConstraintDefault[], mRight, mTop, mVerticalResolution, mVerticalRun, mWeight[], mX, mY, run[], SOLVER, stringId, UNKNOWN, VERTICAL, verticalChainRun, verticalGroup, VISIBLE, WRAP_BEHAVIOR_HORIZONTAL_ONLY, WRAP_BEHAVIOR_INCLUDED, WRAP_BEHAVIOR_SKIPPED, WRAP_BEHAVIOR_VERTICAL_ONLY
Constructors
publicBarrier()

publicBarrier(java.lang.String debugName)

Methods
public voidaddToSolver(LinearSystem system, boolean optimize)

Add this widget to the solver

public booleanallowedInBarrier()

Returns true if this widget should be used in a barrier

public booleanallowsGoneWidget()

Find if this barrier supports gone widgets.

public booleanallSolved()

public voidcopy(ConstraintWidget src, java.util.HashMap<ConstraintWidget, ConstraintWidget> map)

public booleangetAllowsGoneWidget()

Find if this barrier supports gone widgets.

public intgetBarrierType()

public intgetMargin()

public intgetOrientation()

public booleanisResolvedHorizontally()

public booleanisResolvedVertically()

protected voidmarkWidgets()

public voidsetAllowsGoneWidget(boolean allowsGoneWidget)

public voidsetBarrierType(int barrierType)

public voidsetMargin(int margin)

public java.lang.StringtoString()

Returns a string representation of the ConstraintWidget

from HelperWidgetadd, addDependents, findGroupInDependents, removeAllIds, updateConstraints
from ConstraintWidgetaddChildrenToSolverByDependency, connect, connect, connect, connectCircularConstraint, createObjectVariables, ensureMeasureRequested, ensureWidgetRuns, getAnchor, getAnchors, getBaselineDistance, getBiasPercent, getBottom, getCompanionWidget, getContainerItemSkip, getDebugName, getDimensionBehaviour, getDimensionRatio, getDimensionRatioSide, getHasBaseline, getHeight, getHorizontalBiasPercent, getHorizontalChainControlWidget, getHorizontalChainStyle, getHorizontalDimensionBehaviour, getHorizontalMargin, getLastHorizontalMeasureSpec, getLastVerticalMeasureSpec, getLeft, getLength, getMaxHeight, getMaxWidth, getMinHeight, getMinWidth, getNextChainMember, getOptimizerWrapHeight, getOptimizerWrapWidth, getParent, getPreviousChainMember, getRight, getRootX, getRootY, getRun, getSceneString, getTop, getType, getVerticalBiasPercent, getVerticalChainControlWidget, getVerticalChainStyle, getVerticalDimensionBehaviour, getVerticalMargin, getVisibility, getWidth, getWrapBehaviorInParent, getX, getY, hasBaseline, hasDanglingDimension, hasDependencies, hasDimensionOverride, hasResolvedTargets, immediateConnect, isAnimated, isHeightWrapContent, isHorizontalSolvingPassDone, isInBarrier, isInHorizontalChain, isInPlaceholder, isInVerticalChain, isInVirtualLayout, isMeasureRequested, isRoot, isSpreadHeight, isSpreadWidth, isVerticalSolvingPassDone, isWidthWrapContent, markHorizontalSolvingPassDone, markVerticalSolvingPassDone, oppositeDimensionDependsOn, oppositeDimensionsTied, reset, resetAllConstraints, resetAnchor, resetAnchors, resetFinalResolution, resetSolverVariables, resetSolvingPassFlag, serialize, setAnimated, setBaselineDistance, setCompanionWidget, setContainerItemSkip, setDebugName, setDebugSolverName, setDimension, setDimensionRatio, setDimensionRatio, setFinalBaseline, setFinalFrame, setFinalHorizontal, setFinalLeft, setFinalTop, setFinalVertical, setFrame, setFrame, setGoneMargin, setHasBaseline, setHeight, setHeightWrapContent, setHorizontalBiasPercent, setHorizontalChainStyle, setHorizontalDimension, setHorizontalDimensionBehaviour, setHorizontalMatchStyle, setHorizontalWeight, setInBarrier, setInPlaceholder, setInVirtualLayout, setLastMeasureSpec, setLength, setMaxHeight, setMaxWidth, setMeasureRequested, setMinHeight, setMinWidth, setOffset, setOrigin, setParent, setType, setupDimensionRatio, setVerticalBiasPercent, setVerticalChainStyle, setVerticalDimension, setVerticalDimensionBehaviour, setVerticalMatchStyle, setVerticalWeight, setVisibility, setWidth, setWidthWrapContent, setWrapBehaviorInParent, setX, setY, updateFromRuns, updateFromSolver
from java.lang.Objectclone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait

Fields

public static final int LEFT

public static final int RIGHT

public static final int TOP

public static final int BOTTOM

Constructors

public Barrier()

public Barrier(java.lang.String debugName)

Methods

public boolean allowedInBarrier()

Returns true if this widget should be used in a barrier

public int getBarrierType()

public void setBarrierType(int barrierType)

public void setAllowsGoneWidget(boolean allowsGoneWidget)

public boolean allowsGoneWidget()

Deprecated: This method should be called getAllowsGoneWidget such that allowsGoneWidget can be accessed as a property from Kotlin; . Use Barrier.getAllowsGoneWidget() instead.

Find if this barrier supports gone widgets.

Returns:

true if this barrier supports gone widgets, otherwise false

public boolean getAllowsGoneWidget()

Find if this barrier supports gone widgets.

Returns:

true if this barrier supports gone widgets, otherwise false

public boolean isResolvedHorizontally()

public boolean isResolvedVertically()

public void copy(ConstraintWidget src, java.util.HashMap<ConstraintWidget, ConstraintWidget> map)

public java.lang.String toString()

Returns a string representation of the ConstraintWidget

Returns:

string representation of the widget

protected void markWidgets()

public void addToSolver(LinearSystem system, boolean optimize)

Add this widget to the solver

Parameters:

system: the solver we want to add the widget to
optimize: true if Optimizer.OPTIMIZATION_GRAPH is on

public void setMargin(int margin)

public int getMargin()

public int getOrientation()

public boolean allSolved()

Source

/*
 * Copyright (C) 2017 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.LinearSystem;
import androidx.constraintlayout.core.SolverVariable;

import java.util.HashMap;

/**
 * A Barrier takes multiple widgets
 */
public class Barrier extends HelperWidget {

    public static final int LEFT = 0;
    public static final int RIGHT = 1;
    public static final int TOP = 2;
    public static final int BOTTOM = 3;
    private static final boolean USE_RESOLUTION = true;
    private static final boolean USE_RELAX_GONE = false;

    private int mBarrierType = LEFT;

    private boolean mAllowsGoneWidget = true;
    private int mMargin = 0;
    boolean mResolved = false;

    public Barrier() {
    }

    public Barrier(String debugName) {
        setDebugName(debugName);
    }

    @Override
    public boolean allowedInBarrier() {
        return true;
    }

    public int getBarrierType() {
        return mBarrierType;
    }

    public void setBarrierType(int barrierType) {
        mBarrierType = barrierType;
    }

    public void setAllowsGoneWidget(boolean allowsGoneWidget) {
        mAllowsGoneWidget = allowsGoneWidget;
    }

    /**
     * Find if this barrier supports gone widgets.
     *
     * @return true if this barrier supports gone widgets, otherwise false
     * @deprecated This method should be called {@code getAllowsGoneWidget}
     * such that {@code allowsGoneWidget}
     * can be accessed as a property from Kotlin; {@see https://android.github
     * .io/kotlin-guides/interop.html#property-prefixes}.
     * Use {@link #getAllowsGoneWidget()} instead.
     */
    @Deprecated
    public boolean allowsGoneWidget() {
        return mAllowsGoneWidget;
    }

    /**
     * Find if this barrier supports gone widgets.
     *
     * @return true if this barrier supports gone widgets, otherwise false
     */
    public boolean getAllowsGoneWidget() {
        return mAllowsGoneWidget;
    }

    public boolean isResolvedHorizontally() {
        return mResolved;
    }

    public boolean isResolvedVertically() {
        return mResolved;
    }

    @Override
    public void copy(ConstraintWidget src, HashMap<ConstraintWidget, ConstraintWidget> map) {
        super.copy(src, map);
        Barrier srcBarrier = (Barrier) src;
        mBarrierType = srcBarrier.mBarrierType;
        mAllowsGoneWidget = srcBarrier.mAllowsGoneWidget;
        mMargin = srcBarrier.mMargin;
    }

    @Override
    public String toString() {
        String debug = "[Barrier] " + getDebugName() + " {";
        for (int i = 0; i < mWidgetsCount; i++) {
            ConstraintWidget widget = mWidgets[i];
            if (i > 0) {
                debug += ", ";
            }
            debug += widget.getDebugName();
        }
        debug += "}";
        return debug;
    }

    protected void markWidgets() {
        for (int i = 0; i < mWidgetsCount; i++) {
            ConstraintWidget widget = mWidgets[i];
            if (!mAllowsGoneWidget && !widget.allowedInBarrier()) {
                continue;
            }
            if (mBarrierType == LEFT || mBarrierType == RIGHT) {
                widget.setInBarrier(HORIZONTAL, true);
            } else if (mBarrierType == TOP || mBarrierType == BOTTOM) {
                widget.setInBarrier(VERTICAL, true);
            }
        }
    }

    /**
     * Add this widget to the solver
     *
     * @param system   the solver we want to add the widget to
     * @param optimize true if {@link Optimizer#OPTIMIZATION_GRAPH} is on
     */
    @Override
    public void addToSolver(LinearSystem system, boolean optimize) {
        if (LinearSystem.FULL_DEBUG) {
            System.out.println("\n----------------------------------------------");
            System.out.println("-- adding " + getDebugName() + " to the solver");
            System.out.println("----------------------------------------------\n");
        }

        ConstraintAnchor position;
        mListAnchors[LEFT] = mLeft;
        mListAnchors[TOP] = mTop;
        mListAnchors[RIGHT] = mRight;
        mListAnchors[BOTTOM] = mBottom;
        for (int i = 0; i < mListAnchors.length; i++) {
            mListAnchors[i].mSolverVariable = system.createObjectVariable(mListAnchors[i]);
        }
        if (mBarrierType >= 0 && mBarrierType < 4) {
            position = mListAnchors[mBarrierType];
        } else {
            return;
        }

        if (USE_RESOLUTION) {
            if (!mResolved) {
                allSolved();
            }
            if (mResolved) {
                mResolved = false;
                if (mBarrierType == LEFT || mBarrierType == RIGHT) {
                    system.addEquality(mLeft.mSolverVariable, mX);
                    system.addEquality(mRight.mSolverVariable, mX);
                } else if (mBarrierType == TOP || mBarrierType == BOTTOM) {
                    system.addEquality(mTop.mSolverVariable, mY);
                    system.addEquality(mBottom.mSolverVariable, mY);
                }
                return;
            }
        }

        // We have to handle the case where some of the elements
        //  referenced in the barrier are set as
        // match_constraint; we have to take it in account to set the strength of the barrier.
        boolean hasMatchConstraintWidgets = false;
        for (int i = 0; i < mWidgetsCount; i++) {
            ConstraintWidget widget = mWidgets[i];
            if (!mAllowsGoneWidget && !widget.allowedInBarrier()) {
                continue;
            }
            if ((mBarrierType == LEFT || mBarrierType == RIGHT)
                    && (widget.getHorizontalDimensionBehaviour()
                    == DimensionBehaviour.MATCH_CONSTRAINT)
                    && widget.mLeft.mTarget != null && widget.mRight.mTarget != null) {
                hasMatchConstraintWidgets = true;
                break;
            } else if ((mBarrierType == TOP || mBarrierType == BOTTOM)
                    && (widget.getVerticalDimensionBehaviour()
                    == DimensionBehaviour.MATCH_CONSTRAINT)
                    && widget.mTop.mTarget != null && widget.mBottom.mTarget != null) {
                hasMatchConstraintWidgets = true;
                break;
            }
        }

        boolean mHasHorizontalCenteredDependents =
                mLeft.hasCenteredDependents() || mRight.hasCenteredDependents();
        boolean mHasVerticalCenteredDependents =
                mTop.hasCenteredDependents() || mBottom.hasCenteredDependents();
        boolean applyEqualityOnReferences = !hasMatchConstraintWidgets
                && ((mBarrierType == LEFT && mHasHorizontalCenteredDependents)
                || (mBarrierType == TOP && mHasVerticalCenteredDependents)
                || (mBarrierType == RIGHT && mHasHorizontalCenteredDependents)
                || (mBarrierType == BOTTOM && mHasVerticalCenteredDependents));

        int equalityOnReferencesStrength = SolverVariable.STRENGTH_EQUALITY;
        if (!applyEqualityOnReferences) {
            equalityOnReferencesStrength = SolverVariable.STRENGTH_HIGHEST;
        }
        for (int i = 0; i < mWidgetsCount; i++) {
            ConstraintWidget widget = mWidgets[i];
            if (!mAllowsGoneWidget && !widget.allowedInBarrier()) {
                continue;
            }
            SolverVariable target = system.createObjectVariable(widget.mListAnchors[mBarrierType]);
            widget.mListAnchors[mBarrierType].mSolverVariable = target;
            int margin = 0;
            if (widget.mListAnchors[mBarrierType].mTarget != null
                    && widget.mListAnchors[mBarrierType].mTarget.mOwner == this) {
                margin += widget.mListAnchors[mBarrierType].mMargin;
            }
            if (mBarrierType == LEFT || mBarrierType == TOP) {
                system.addLowerBarrier(position.mSolverVariable, target,
                        mMargin - margin, hasMatchConstraintWidgets);
            } else {
                system.addGreaterBarrier(position.mSolverVariable, target,
                        mMargin + margin, hasMatchConstraintWidgets);
            }
            if (USE_RELAX_GONE) {
                if (widget.getVisibility() != GONE
                        || widget instanceof Guideline || widget instanceof Barrier) {
                    system.addEquality(position.mSolverVariable, target,
                            mMargin + margin, equalityOnReferencesStrength);
                }
            } else {
                system.addEquality(position.mSolverVariable, target,
                        mMargin + margin, equalityOnReferencesStrength);
            }
        }

        int barrierParentStrength = SolverVariable.STRENGTH_HIGHEST;
        int barrierParentStrengthOpposite = SolverVariable.STRENGTH_NONE;

        if (mBarrierType == LEFT) {
            system.addEquality(mRight.mSolverVariable,
                    mLeft.mSolverVariable, 0, SolverVariable.STRENGTH_FIXED);
            system.addEquality(mLeft.mSolverVariable,
                    mParent.mRight.mSolverVariable, 0, barrierParentStrength);
            system.addEquality(mLeft.mSolverVariable,
                    mParent.mLeft.mSolverVariable, 0, barrierParentStrengthOpposite);
        } else if (mBarrierType == RIGHT) {
            system.addEquality(mLeft.mSolverVariable,
                    mRight.mSolverVariable, 0, SolverVariable.STRENGTH_FIXED);
            system.addEquality(mLeft.mSolverVariable,
                    mParent.mLeft.mSolverVariable, 0, barrierParentStrength);
            system.addEquality(mLeft.mSolverVariable,
                    mParent.mRight.mSolverVariable, 0, barrierParentStrengthOpposite);
        } else if (mBarrierType == TOP) {
            system.addEquality(mBottom.mSolverVariable,
                    mTop.mSolverVariable, 0, SolverVariable.STRENGTH_FIXED);
            system.addEquality(mTop.mSolverVariable,
                    mParent.mBottom.mSolverVariable, 0, barrierParentStrength);
            system.addEquality(mTop.mSolverVariable,
                    mParent.mTop.mSolverVariable, 0, barrierParentStrengthOpposite);
        } else if (mBarrierType == BOTTOM) {
            system.addEquality(mTop.mSolverVariable,
                    mBottom.mSolverVariable, 0, SolverVariable.STRENGTH_FIXED);
            system.addEquality(mTop.mSolverVariable,
                    mParent.mTop.mSolverVariable, 0, barrierParentStrength);
            system.addEquality(mTop.mSolverVariable,
                    mParent.mBottom.mSolverVariable, 0, barrierParentStrengthOpposite);
        }
    }

    public void setMargin(int margin) {
        mMargin = margin;
    }

    public int getMargin() {
        return mMargin;
    }

    /**
     * @TODO: add description
     */
    public int getOrientation() {
        switch (mBarrierType) {
            case LEFT:
            case RIGHT:
                return HORIZONTAL;
            case TOP:
            case BOTTOM:
                return VERTICAL;
        }
        return UNKNOWN;
    }

    /**
     * @TODO: add description
     */
    public boolean allSolved() {
        if (!USE_RESOLUTION) {
            return false;
        }
        boolean hasAllWidgetsResolved = true;
        for (int i = 0; i < mWidgetsCount; i++) {
            ConstraintWidget widget = mWidgets[i];
            if (!mAllowsGoneWidget && !widget.allowedInBarrier()) {
                continue;
            }
            if ((mBarrierType == LEFT || mBarrierType == RIGHT)
                    && !widget.isResolvedHorizontally()) {
                hasAllWidgetsResolved = false;
            } else if ((mBarrierType == TOP || mBarrierType == BOTTOM)
                    && !widget.isResolvedVertically()) {
                hasAllWidgetsResolved = false;
            }
        }

        if (hasAllWidgetsResolved && mWidgetsCount > 0) {
            // we're done!
            int barrierPosition = 0;
            boolean initialized = false;
            for (int i = 0; i < mWidgetsCount; i++) {
                ConstraintWidget widget = mWidgets[i];
                if (!mAllowsGoneWidget && !widget.allowedInBarrier()) {
                    continue;
                }
                if (!initialized) {
                    if (mBarrierType == LEFT) {
                        barrierPosition =
                                widget.getAnchor(ConstraintAnchor.Type.LEFT).getFinalValue();
                    } else if (mBarrierType == RIGHT) {
                        barrierPosition =
                                widget.getAnchor(ConstraintAnchor.Type.RIGHT).getFinalValue();
                    } else if (mBarrierType == TOP) {
                        barrierPosition =
                                widget.getAnchor(ConstraintAnchor.Type.TOP).getFinalValue();
                    } else if (mBarrierType == BOTTOM) {
                        barrierPosition =
                                widget.getAnchor(ConstraintAnchor.Type.BOTTOM).getFinalValue();
                    }
                    initialized = true;
                }
                if (mBarrierType == LEFT) {
                    barrierPosition = Math.min(barrierPosition,
                            widget.getAnchor(ConstraintAnchor.Type.LEFT).getFinalValue());
                } else if (mBarrierType == RIGHT) {
                    barrierPosition = Math.max(barrierPosition,
                            widget.getAnchor(ConstraintAnchor.Type.RIGHT).getFinalValue());
                } else if (mBarrierType == TOP) {
                    barrierPosition = Math.min(barrierPosition,
                            widget.getAnchor(ConstraintAnchor.Type.TOP).getFinalValue());
                } else if (mBarrierType == BOTTOM) {
                    barrierPosition = Math.max(barrierPosition,
                            widget.getAnchor(ConstraintAnchor.Type.BOTTOM).getFinalValue());
                }
            }
            barrierPosition += mMargin;
            if (mBarrierType == LEFT || mBarrierType == RIGHT) {
                setFinalHorizontal(barrierPosition, barrierPosition);
            } else {
                setFinalVertical(barrierPosition, barrierPosition);
            }
            if (LinearSystem.FULL_DEBUG) {
                System.out.println("*** BARRIER " + getDebugName()
                        + " SOLVED TO " + barrierPosition + " ***");
            }
            mResolved = true;
            return true;
        }
        return false;
    }
}