public class

ConstraintReference

extends java.lang.Object

implements Reference

 java.lang.Object

↳androidx.constraintlayout.core.state.ConstraintReference

Subclasses:

HelperReference, BarrierReference, VerticalChainReference, ChainReference, AlignHorizontallyReference, HorizontalChainReference, AlignVerticallyReference

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/)

Summary

Fields
protected java.lang.ObjectmBottomToBottom

protected java.lang.ObjectmBottomToTop

protected java.lang.ObjectmEndToEnd

protected java.lang.ObjectmEndToStart

protected java.lang.ObjectmLeftToLeft

protected java.lang.ObjectmLeftToRight

protected intmMarginBottom

protected intmMarginBottomGone

protected intmMarginEnd

protected intmMarginEndGone

protected intmMarginLeft

protected intmMarginLeftGone

protected intmMarginRight

protected intmMarginRightGone

protected intmMarginStart

protected intmMarginStartGone

protected intmMarginTop

protected intmMarginTopGone

protected java.lang.ObjectmRightToLeft

protected java.lang.ObjectmRightToRight

protected java.lang.ObjectmStartToEnd

protected java.lang.ObjectmStartToStart

protected java.lang.ObjectmTopToBottom

protected java.lang.ObjectmTopToTop

Constructors
publicConstraintReference(State state)

Methods
public voidaddCustomColor(java.lang.String name, int color)

public voidaddCustomFloat(java.lang.String name, float value)

public ConstraintReferencealpha(float alpha)

public voidapply()

public ConstraintReferencebaseline()

public ConstraintReferencebaselineToBaseline(java.lang.Object reference)

public ConstraintReferencebaselineToBottom(java.lang.Object reference)

public ConstraintReferencebaselineToTop(java.lang.Object reference)

public ConstraintReferencebias(float value)

public ConstraintReferencebottom()

public ConstraintReferencebottomToBottom(java.lang.Object reference)

public ConstraintReferencebottomToTop(java.lang.Object reference)

public ConstraintReferencecenterHorizontally(java.lang.Object reference)

public ConstraintReferencecenterVertically(java.lang.Object reference)

public ConstraintReferencecircularConstraint(java.lang.Object reference, float angle, float distance)

public ConstraintReferenceclear()

public ConstraintReferenceclearHorizontal()

public ConstraintReferenceclearVertical()

public ConstraintWidgetcreateConstraintWidget()

public ConstraintReferenceend()

public ConstraintReferenceendToEnd(java.lang.Object reference)

public ConstraintReferenceendToStart(java.lang.Object reference)

public floatgetAlpha()

public ConstraintWidgetgetConstraintWidget()

public FacadegetFacade()

public DimensiongetHeight()

public intgetHorizontalChainStyle()

public floatgetHorizontalChainWeight()

public java.lang.ObjectgetKey()

public floatgetPivotX()

public floatgetPivotY()

public floatgetRotationX()

public floatgetRotationY()

public floatgetRotationZ()

public floatgetScaleX()

public floatgetScaleY()

public java.lang.StringgetTag()

public floatgetTranslationX()

public floatgetTranslationY()

public floatgetTranslationZ()

public intgetVerticalChainStyle(int chainStyle)

public floatgetVerticalChainWeight()

public java.lang.ObjectgetView()

public DimensiongetWidth()

public ConstraintReferenceheight(Dimension dimension)

public ConstraintReferencehorizontalBias(float value)

public ConstraintReferenceleft()

public ConstraintReferenceleftToLeft(java.lang.Object reference)

public ConstraintReferenceleftToRight(java.lang.Object reference)

public ConstraintReferencemargin(int value)

public ConstraintReferencemargin(java.lang.Object marginValue)

public ConstraintReferencemarginGone(int value)

public ConstraintReferencemarginGone(java.lang.Object marginGoneValue)

public ConstraintReferencepivotX(float x)

public ConstraintReferencepivotY(float y)

public ConstraintReferenceright()

public ConstraintReferencerightToLeft(java.lang.Object reference)

public ConstraintReferencerightToRight(java.lang.Object reference)

public ConstraintReferencerotationX(float x)

public ConstraintReferencerotationY(float y)

public ConstraintReferencerotationZ(float z)

public ConstraintReferencescaleX(float x)

public ConstraintReferencescaleY(float y)

public voidsetConstraintWidget(ConstraintWidget widget)

public voidsetFacade(Facade facade)

public ConstraintReferencesetHeight(Dimension dimension)

public voidsetHorizontalChainStyle(int chainStyle)

public voidsetHorizontalChainWeight(float weight)

public voidsetKey(java.lang.Object key)

public voidsetTag(java.lang.String tag)

public voidsetVerticalChainStyle(int chainStyle)

public voidsetVerticalChainWeight(float weight)

public voidsetView(java.lang.Object view)

public ConstraintReferencesetWidth(Dimension dimension)

public ConstraintReferencestart()

public ConstraintReferencestartToEnd(java.lang.Object reference)

public ConstraintReferencestartToStart(java.lang.Object reference)

public ConstraintReferencetop()

public ConstraintReferencetopToBottom(java.lang.Object reference)

public ConstraintReferencetopToTop(java.lang.Object reference)

public ConstraintReferencetranslationX(float x)

public ConstraintReferencetranslationY(float y)

public ConstraintReferencetranslationZ(float z)

public voidvalidate()

Validate the constraints

public ConstraintReferenceverticalBias(float value)

public ConstraintReferencevisibility(int visibility)

public ConstraintReferencewidth(Dimension dimension)

from java.lang.Objectclone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Fields

protected int mMarginLeft

protected int mMarginRight

protected int mMarginStart

protected int mMarginEnd

protected int mMarginTop

protected int mMarginBottom

protected int mMarginLeftGone

protected int mMarginRightGone

protected int mMarginStartGone

protected int mMarginEndGone

protected int mMarginTopGone

protected int mMarginBottomGone

protected java.lang.Object mLeftToLeft

protected java.lang.Object mLeftToRight

protected java.lang.Object mRightToLeft

protected java.lang.Object mRightToRight

protected java.lang.Object mStartToStart

protected java.lang.Object mStartToEnd

protected java.lang.Object mEndToStart

protected java.lang.Object mEndToEnd

protected java.lang.Object mTopToTop

protected java.lang.Object mTopToBottom

protected java.lang.Object mBottomToTop

protected java.lang.Object mBottomToBottom

Constructors

public ConstraintReference(State state)

Methods

public void setKey(java.lang.Object key)

public java.lang.Object getKey()

public void setTag(java.lang.String tag)

public java.lang.String getTag()

public void setView(java.lang.Object view)

public java.lang.Object getView()

public void setFacade(Facade facade)

public Facade getFacade()

public void setConstraintWidget(ConstraintWidget widget)

public ConstraintWidget getConstraintWidget()

public ConstraintWidget createConstraintWidget()

public void validate()

Validate the constraints

public void setHorizontalChainStyle(int chainStyle)

public int getHorizontalChainStyle()

public void setVerticalChainStyle(int chainStyle)

public int getVerticalChainStyle(int chainStyle)

public float getHorizontalChainWeight()

public void setHorizontalChainWeight(float weight)

public float getVerticalChainWeight()

public void setVerticalChainWeight(float weight)

public ConstraintReference clearVertical()

public ConstraintReference clearHorizontal()

public float getTranslationX()

public float getTranslationY()

public float getTranslationZ()

public float getScaleX()

public float getScaleY()

public float getAlpha()

public float getPivotX()

public float getPivotY()

public float getRotationX()

public float getRotationY()

public float getRotationZ()

public ConstraintReference pivotX(float x)

public ConstraintReference pivotY(float y)

public ConstraintReference rotationX(float x)

public ConstraintReference rotationY(float y)

public ConstraintReference rotationZ(float z)

public ConstraintReference translationX(float x)

public ConstraintReference translationY(float y)

public ConstraintReference translationZ(float z)

public ConstraintReference scaleX(float x)

public ConstraintReference scaleY(float y)

public ConstraintReference alpha(float alpha)

public ConstraintReference visibility(int visibility)

public ConstraintReference left()

public ConstraintReference right()

public ConstraintReference start()

public ConstraintReference end()

public ConstraintReference top()

public ConstraintReference bottom()

public ConstraintReference baseline()

public void addCustomColor(java.lang.String name, int color)

public void addCustomFloat(java.lang.String name, float value)

public ConstraintReference leftToLeft(java.lang.Object reference)

public ConstraintReference leftToRight(java.lang.Object reference)

public ConstraintReference rightToLeft(java.lang.Object reference)

public ConstraintReference rightToRight(java.lang.Object reference)

public ConstraintReference startToStart(java.lang.Object reference)

public ConstraintReference startToEnd(java.lang.Object reference)

public ConstraintReference endToStart(java.lang.Object reference)

public ConstraintReference endToEnd(java.lang.Object reference)

public ConstraintReference topToTop(java.lang.Object reference)

public ConstraintReference topToBottom(java.lang.Object reference)

public ConstraintReference bottomToTop(java.lang.Object reference)

public ConstraintReference bottomToBottom(java.lang.Object reference)

public ConstraintReference baselineToBaseline(java.lang.Object reference)

public ConstraintReference baselineToTop(java.lang.Object reference)

public ConstraintReference baselineToBottom(java.lang.Object reference)

public ConstraintReference centerHorizontally(java.lang.Object reference)

public ConstraintReference centerVertically(java.lang.Object reference)

public ConstraintReference circularConstraint(java.lang.Object reference, float angle, float distance)

public ConstraintReference width(Dimension dimension)

public ConstraintReference height(Dimension dimension)

public Dimension getWidth()

public ConstraintReference setWidth(Dimension dimension)

public Dimension getHeight()

public ConstraintReference setHeight(Dimension dimension)

public ConstraintReference margin(java.lang.Object marginValue)

public ConstraintReference marginGone(java.lang.Object marginGoneValue)

public ConstraintReference margin(int value)

public ConstraintReference marginGone(int value)

public ConstraintReference horizontalBias(float value)

public ConstraintReference verticalBias(float value)

public ConstraintReference bias(float value)

public ConstraintReference clear()

public void apply()

Source

/*
 * 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.state;

import static androidx.constraintlayout.core.widgets.ConstraintWidget.HORIZONTAL;
import static androidx.constraintlayout.core.widgets.ConstraintWidget.UNKNOWN;
import static androidx.constraintlayout.core.widgets.ConstraintWidget.VERTICAL;

import androidx.constraintlayout.core.motion.utils.TypedBundle;
import androidx.constraintlayout.core.motion.utils.TypedValues;
import androidx.constraintlayout.core.state.helpers.Facade;
import androidx.constraintlayout.core.widgets.ConstraintAnchor;
import androidx.constraintlayout.core.widgets.ConstraintWidget;

import java.util.ArrayList;
import java.util.HashMap;

public class ConstraintReference implements Reference {

    private Object mKey;

    public void setKey(Object key) {
        this.mKey = key;
    }

    public Object getKey() {
        return mKey;
    }

    public void setTag(String tag) {
        mTag = tag;
    }

    public String getTag() {
        return mTag;
    }

    public interface ConstraintReferenceFactory {
        /**
         * @TODO: add description
         */
        ConstraintReference create(State state);
    }

    final State mState;

    String mTag = null;

    Facade mFacade = null;

    int mHorizontalChainStyle = ConstraintWidget.CHAIN_SPREAD;
    int mVerticalChainStyle = ConstraintWidget.CHAIN_SPREAD;

    float mHorizontalChainWeight = UNKNOWN;
    float mVerticalChainWeight = UNKNOWN;

    float mHorizontalBias = 0.5f;
    float mVerticalBias = 0.5f;

    protected int mMarginLeft = 0;
    protected int mMarginRight = 0;
    protected int mMarginStart = 0;
    protected int mMarginEnd = 0;
    protected int mMarginTop = 0;
    protected int mMarginBottom = 0;

    protected int mMarginLeftGone = 0;
    protected int mMarginRightGone = 0;
    protected int mMarginStartGone = 0;
    protected int mMarginEndGone = 0;
    protected int mMarginTopGone = 0;
    protected int mMarginBottomGone = 0;

    int mMarginBaseline = 0;
    int mMarginBaselineGone = 0;

    float mPivotX = Float.NaN;
    float mPivotY = Float.NaN;

    float mRotationX = Float.NaN;
    float mRotationY = Float.NaN;
    float mRotationZ = Float.NaN;

    float mTranslationX = Float.NaN;
    float mTranslationY = Float.NaN;
    float mTranslationZ = Float.NaN;

    float mAlpha = Float.NaN;

    float mScaleX = Float.NaN;
    float mScaleY = Float.NaN;

    int mVisibility = ConstraintWidget.VISIBLE;

    protected Object mLeftToLeft = null;
    protected Object mLeftToRight = null;
    protected Object mRightToLeft = null;
    protected Object mRightToRight = null;
    protected Object mStartToStart = null;
    protected Object mStartToEnd = null;
    protected Object mEndToStart = null;
    protected Object mEndToEnd = null;
    protected Object mTopToTop = null;
    protected Object mTopToBottom = null;
    protected Object mBottomToTop = null;
    protected Object mBottomToBottom = null;
    Object mBaselineToBaseline = null;
    Object mBaselineToTop = null;
    Object mBaselineToBottom = null;
    Object mCircularConstraint = null;
    private float mCircularAngle;
    private float mCircularDistance;

    State.Constraint mLast = null;

    Dimension mHorizontalDimension = Dimension.createFixed(Dimension.WRAP_DIMENSION);
    Dimension mVerticalDimension = Dimension.createFixed(Dimension.WRAP_DIMENSION);

    private Object mView;
    private ConstraintWidget mConstraintWidget;

    private HashMap<String, Integer> mCustomColors = new HashMap<>();
    private HashMap<String, Float> mCustomFloats = new HashMap<>();

    TypedBundle mMotionProperties = null;

    /**
     * @TODO: add description
     */
    public void setView(Object view) {
        mView = view;
        if (mConstraintWidget != null) {
            mConstraintWidget.setCompanionWidget(mView);
        }
    }

    public Object getView() {
        return mView;
    }

    /**
     * @TODO: add description
     */
    public void setFacade(Facade facade) {
        mFacade = facade;
        if (facade != null) {
            setConstraintWidget(facade.getConstraintWidget());
        }
    }

    public Facade getFacade() {
        return mFacade;
    }

    /**
     * @TODO: add description
     */
    public void setConstraintWidget(ConstraintWidget widget) {
        if (widget == null) {
            return;
        }
        mConstraintWidget = widget;
        mConstraintWidget.setCompanionWidget(mView);
    }

    @Override
    public ConstraintWidget getConstraintWidget() {
        if (mConstraintWidget == null) {
            mConstraintWidget = createConstraintWidget();
            mConstraintWidget.setCompanionWidget(mView);
        }
        return mConstraintWidget;
    }

    /**
     * @TODO: add description
     */
    public ConstraintWidget createConstraintWidget() {
        return new ConstraintWidget(
                getWidth().getValue(),
                getHeight().getValue());
    }

    static class IncorrectConstraintException extends Exception {

        private final ArrayList<String> mErrors;

        IncorrectConstraintException(ArrayList<String> errors) {
            mErrors = errors;
        }

        public ArrayList<String> getErrors() {
            return mErrors;
        }

        @Override
        public String toString() {
            return "IncorrectConstraintException: " + mErrors.toString();
        }
    }

    /**
     * Validate the constraints
     */
    public void validate() throws IncorrectConstraintException {
        ArrayList<String> errors = new ArrayList<>();
        if (mLeftToLeft != null && mLeftToRight != null) {
            errors.add("LeftToLeft and LeftToRight both defined");
        }
        if (mRightToLeft != null && mRightToRight != null) {
            errors.add("RightToLeft and RightToRight both defined");
        }
        if (mStartToStart != null && mStartToEnd != null) {
            errors.add("StartToStart and StartToEnd both defined");
        }
        if (mEndToStart != null && mEndToEnd != null) {
            errors.add("EndToStart and EndToEnd both defined");
        }
        if ((mLeftToLeft != null || mLeftToRight != null
                || mRightToLeft != null || mRightToRight != null)
                && (mStartToStart != null || mStartToEnd != null
                || mEndToStart != null || mEndToEnd != null)) {
            errors.add("Both left/right and start/end constraints defined");
        }
        if (errors.size() > 0) {
            throw new IncorrectConstraintException(errors);
        }
    }

    private Object get(Object reference) {
        if (reference == null) {
            return null;
        }
        if (!(reference instanceof ConstraintReference)) {
            return mState.reference(reference);
        }
        return reference;
    }

    public ConstraintReference(State state) {
        mState = state;
    }

    public void setHorizontalChainStyle(int chainStyle) {
        mHorizontalChainStyle = chainStyle;
    }

    public int getHorizontalChainStyle() {
        return mHorizontalChainStyle;
    }

    public void setVerticalChainStyle(int chainStyle) {
        mVerticalChainStyle = chainStyle;
    }

    /**
     * @TODO: add description
     */
    public int getVerticalChainStyle(int chainStyle) {
        return mVerticalChainStyle;
    }

    public float getHorizontalChainWeight() {
        return mHorizontalChainWeight;
    }

    public void setHorizontalChainWeight(float weight) {
        mHorizontalChainWeight = weight;
    }

    public float getVerticalChainWeight() {
        return mVerticalChainWeight;
    }

    public void setVerticalChainWeight(float weight) {
        mVerticalChainWeight = weight;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference clearVertical() {
        top().clear();
        baseline().clear();
        bottom().clear();
        return this;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference clearHorizontal() {
        start().clear();
        end().clear();
        left().clear();
        right().clear();
        return this;
    }

    public float getTranslationX() {
        return mTranslationX;
    }

    public float getTranslationY() {
        return mTranslationY;
    }

    public float getTranslationZ() {
        return mTranslationZ;
    }

    public float getScaleX() {
        return mScaleX;
    }

    public float getScaleY() {
        return mScaleY;
    }

    public float getAlpha() {
        return mAlpha;
    }

    public float getPivotX() {
        return mPivotX;
    }

    public float getPivotY() {
        return mPivotY;
    }

    public float getRotationX() {
        return mRotationX;
    }

    public float getRotationY() {
        return mRotationY;
    }

    public float getRotationZ() {
        return mRotationZ;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference pivotX(float x) {
        mPivotX = x;
        return this;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference pivotY(float y) {
        mPivotY = y;
        return this;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference rotationX(float x) {
        mRotationX = x;
        return this;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference rotationY(float y) {
        mRotationY = y;
        return this;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference rotationZ(float z) {
        mRotationZ = z;
        return this;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference translationX(float x) {
        mTranslationX = x;
        return this;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference translationY(float y) {
        mTranslationY = y;
        return this;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference translationZ(float z) {
        mTranslationZ = z;
        return this;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference scaleX(float x) {
        mScaleX = x;
        return this;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference scaleY(float y) {
        mScaleY = y;
        return this;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference alpha(float alpha) {
        mAlpha = alpha;
        return this;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference visibility(int visibility) {
        mVisibility = visibility;
        return this;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference left() {
        if (mLeftToLeft != null) {
            mLast = State.Constraint.LEFT_TO_LEFT;
        } else {
            mLast = State.Constraint.LEFT_TO_RIGHT;
        }
        return this;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference right() {
        if (mRightToLeft != null) {
            mLast = State.Constraint.RIGHT_TO_LEFT;
        } else {
            mLast = State.Constraint.RIGHT_TO_RIGHT;
        }
        return this;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference start() {
        if (mStartToStart != null) {
            mLast = State.Constraint.START_TO_START;
        } else {
            mLast = State.Constraint.START_TO_END;
        }
        return this;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference end() {
        if (mEndToStart != null) {
            mLast = State.Constraint.END_TO_START;
        } else {
            mLast = State.Constraint.END_TO_END;
        }
        return this;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference top() {
        if (mTopToTop != null) {
            mLast = State.Constraint.TOP_TO_TOP;
        } else {
            mLast = State.Constraint.TOP_TO_BOTTOM;
        }
        return this;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference bottom() {
        if (mBottomToTop != null) {
            mLast = State.Constraint.BOTTOM_TO_TOP;
        } else {
            mLast = State.Constraint.BOTTOM_TO_BOTTOM;
        }
        return this;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference baseline() {
        mLast = State.Constraint.BASELINE_TO_BASELINE;
        return this;
    }

    /**
     * @TODO: add description
     */
    public void addCustomColor(String name, int color) {
        mCustomColors.put(name, color);
    }

    /**
     * @TODO: add description
     */
    public void addCustomFloat(String name, float value) {
        if (mCustomFloats == null) {
            mCustomFloats = new HashMap<>();
        }
        mCustomFloats.put(name, value);
    }

    private void dereference() {
        mLeftToLeft = get(mLeftToLeft);
        mLeftToRight = get(mLeftToRight);
        mRightToLeft = get(mRightToLeft);
        mRightToRight = get(mRightToRight);
        mStartToStart = get(mStartToStart);
        mStartToEnd = get(mStartToEnd);
        mEndToStart = get(mEndToStart);
        mEndToEnd = get(mEndToEnd);
        mTopToTop = get(mTopToTop);
        mTopToBottom = get(mTopToBottom);
        mBottomToTop = get(mBottomToTop);
        mBottomToBottom = get(mBottomToBottom);
        mBaselineToBaseline = get(mBaselineToBaseline);
        mBaselineToTop = get(mBaselineToTop);
        mBaselineToBottom = get(mBaselineToBottom);
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference leftToLeft(Object reference) {
        mLast = State.Constraint.LEFT_TO_LEFT;
        mLeftToLeft = reference;
        return this;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference leftToRight(Object reference) {
        mLast = State.Constraint.LEFT_TO_RIGHT;
        mLeftToRight = reference;
        return this;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference rightToLeft(Object reference) {
        mLast = State.Constraint.RIGHT_TO_LEFT;
        mRightToLeft = reference;
        return this;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference rightToRight(Object reference) {
        mLast = State.Constraint.RIGHT_TO_RIGHT;
        mRightToRight = reference;
        return this;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference startToStart(Object reference) {
        mLast = State.Constraint.START_TO_START;
        mStartToStart = reference;
        return this;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference startToEnd(Object reference) {
        mLast = State.Constraint.START_TO_END;
        mStartToEnd = reference;
        return this;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference endToStart(Object reference) {
        mLast = State.Constraint.END_TO_START;
        mEndToStart = reference;
        return this;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference endToEnd(Object reference) {
        mLast = State.Constraint.END_TO_END;
        mEndToEnd = reference;
        return this;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference topToTop(Object reference) {
        mLast = State.Constraint.TOP_TO_TOP;
        mTopToTop = reference;
        return this;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference topToBottom(Object reference) {
        mLast = State.Constraint.TOP_TO_BOTTOM;
        mTopToBottom = reference;
        return this;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference bottomToTop(Object reference) {
        mLast = State.Constraint.BOTTOM_TO_TOP;
        mBottomToTop = reference;
        return this;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference bottomToBottom(Object reference) {
        mLast = State.Constraint.BOTTOM_TO_BOTTOM;
        mBottomToBottom = reference;
        return this;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference baselineToBaseline(Object reference) {
        mLast = State.Constraint.BASELINE_TO_BASELINE;
        mBaselineToBaseline = reference;
        return this;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference baselineToTop(Object reference) {
        mLast = State.Constraint.BASELINE_TO_TOP;
        mBaselineToTop = reference;
        return this;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference baselineToBottom(Object reference) {
        mLast = State.Constraint.BASELINE_TO_BOTTOM;
        mBaselineToBottom = reference;
        return this;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference centerHorizontally(Object reference) {
        Object ref = get(reference);
        mStartToStart = ref;
        mEndToEnd = ref;
        mLast = State.Constraint.CENTER_HORIZONTALLY;
        mHorizontalBias = 0.5f;
        return this;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference centerVertically(Object reference) {
        Object ref = get(reference);
        mTopToTop = ref;
        mBottomToBottom = ref;
        mLast = State.Constraint.CENTER_VERTICALLY;
        mVerticalBias = 0.5f;
        return this;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference circularConstraint(Object reference, float angle, float distance) {
        Object ref = get(reference);
        mCircularConstraint = ref;
        mCircularAngle = angle;
        mCircularDistance = distance;
        mLast = State.Constraint.CIRCULAR_CONSTRAINT;
        return this;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference width(Dimension dimension) {
        return setWidth(dimension);
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference height(Dimension dimension) {
        return setHeight(dimension);
    }

    public Dimension getWidth() {
        return mHorizontalDimension;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference setWidth(Dimension dimension) {
        mHorizontalDimension = dimension;
        return this;
    }

    public Dimension getHeight() {
        return mVerticalDimension;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference setHeight(Dimension dimension) {
        mVerticalDimension = dimension;
        return this;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference margin(Object marginValue) {
        return margin(mState.convertDimension(marginValue));
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference marginGone(Object marginGoneValue) {
        return marginGone(mState.convertDimension(marginGoneValue));
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference margin(int value) {
        if (mLast != null) {
            switch (mLast) {
                case LEFT_TO_LEFT:
                case LEFT_TO_RIGHT: {
                    mMarginLeft = value;
                }
                break;
                case RIGHT_TO_LEFT:
                case RIGHT_TO_RIGHT: {
                    mMarginRight = value;
                }
                break;
                case START_TO_START:
                case START_TO_END: {
                    mMarginStart = value;
                }
                break;
                case END_TO_START:
                case END_TO_END: {
                    mMarginEnd = value;
                }
                break;
                case TOP_TO_TOP:
                case TOP_TO_BOTTOM: {
                    mMarginTop = value;
                }
                break;
                case BOTTOM_TO_TOP:
                case BOTTOM_TO_BOTTOM: {
                    mMarginBottom = value;
                }
                break;
                case BASELINE_TO_BOTTOM:
                case BASELINE_TO_TOP:
                case BASELINE_TO_BASELINE: {
                    mMarginBaseline = value;
                }
                break;
                case CIRCULAR_CONSTRAINT: {
                    mCircularDistance = value;
                }
                break;
                default:
                    break;
            }
        } else {
            mMarginLeft = value;
            mMarginRight = value;
            mMarginStart = value;
            mMarginEnd = value;
            mMarginTop = value;
            mMarginBottom = value;
        }
        return this;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference marginGone(int value) {
        if (mLast != null) {
            switch (mLast) {
                case LEFT_TO_LEFT:
                case LEFT_TO_RIGHT: {
                    mMarginLeftGone = value;
                }
                break;
                case RIGHT_TO_LEFT:
                case RIGHT_TO_RIGHT: {
                    mMarginRightGone = value;
                }
                break;
                case START_TO_START:
                case START_TO_END: {
                    mMarginStartGone = value;
                }
                break;
                case END_TO_START:
                case END_TO_END: {
                    mMarginEndGone = value;
                }
                break;
                case TOP_TO_TOP:
                case TOP_TO_BOTTOM: {
                    mMarginTopGone = value;
                }
                break;
                case BOTTOM_TO_TOP:
                case BOTTOM_TO_BOTTOM: {
                    mMarginBottomGone = value;
                }
                break;
                case BASELINE_TO_TOP:
                case BASELINE_TO_BOTTOM:
                case BASELINE_TO_BASELINE: {
                    mMarginBaselineGone = value;
                }
                break;
                default:
                    break;
            }
        } else {
            mMarginLeftGone = value;
            mMarginRightGone = value;
            mMarginStartGone = value;
            mMarginEndGone = value;
            mMarginTopGone = value;
            mMarginBottomGone = value;
        }
        return this;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference horizontalBias(float value) {
        mHorizontalBias = value;
        return this;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference verticalBias(float value) {
        mVerticalBias = value;
        return this;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference bias(float value) {
        if (mLast == null) {
            return this;
        }
        switch (mLast) {
            case CENTER_HORIZONTALLY:
            case LEFT_TO_LEFT:
            case LEFT_TO_RIGHT:
            case RIGHT_TO_LEFT:
            case RIGHT_TO_RIGHT:
            case START_TO_START:
            case START_TO_END:
            case END_TO_START:
            case END_TO_END: {
                mHorizontalBias = value;
            }
            break;
            case CENTER_VERTICALLY:
            case TOP_TO_TOP:
            case TOP_TO_BOTTOM:
            case BOTTOM_TO_TOP:
            case BOTTOM_TO_BOTTOM: {
                mVerticalBias = value;
            }
            break;
            default:
                break;
        }
        return this;
    }

    /**
     * @TODO: add description
     */
    public ConstraintReference clear() {
        if (mLast != null) {
            switch (mLast) {
                case LEFT_TO_LEFT:
                case LEFT_TO_RIGHT: {
                    mLeftToLeft = null;
                    mLeftToRight = null;
                    mMarginLeft = 0;
                    mMarginLeftGone = 0;
                }
                break;
                case RIGHT_TO_LEFT:
                case RIGHT_TO_RIGHT: {
                    mRightToLeft = null;
                    mRightToRight = null;
                    mMarginRight = 0;
                    mMarginRightGone = 0;
                }
                break;
                case START_TO_START:
                case START_TO_END: {
                    mStartToStart = null;
                    mStartToEnd = null;
                    mMarginStart = 0;
                    mMarginStartGone = 0;
                }
                break;
                case END_TO_START:
                case END_TO_END: {
                    mEndToStart = null;
                    mEndToEnd = null;
                    mMarginEnd = 0;
                    mMarginEndGone = 0;
                }
                break;
                case TOP_TO_TOP:
                case TOP_TO_BOTTOM: {
                    mTopToTop = null;
                    mTopToBottom = null;
                    mMarginTop = 0;
                    mMarginTopGone = 0;
                }
                break;
                case BOTTOM_TO_TOP:
                case BOTTOM_TO_BOTTOM: {
                    mBottomToTop = null;
                    mBottomToBottom = null;
                    mMarginBottom = 0;
                    mMarginBottomGone = 0;
                }
                break;
                case BASELINE_TO_BASELINE: {
                    mBaselineToBaseline = null;
                }
                break;
                case CIRCULAR_CONSTRAINT: {
                    mCircularConstraint = null;
                }
                break;
                default:
                    break;
            }
        } else {
            mLeftToLeft = null;
            mLeftToRight = null;
            mMarginLeft = 0;
            mRightToLeft = null;
            mRightToRight = null;
            mMarginRight = 0;
            mStartToStart = null;
            mStartToEnd = null;
            mMarginStart = 0;
            mEndToStart = null;
            mEndToEnd = null;
            mMarginEnd = 0;
            mTopToTop = null;
            mTopToBottom = null;
            mMarginTop = 0;
            mBottomToTop = null;
            mBottomToBottom = null;
            mMarginBottom = 0;
            mBaselineToBaseline = null;
            mCircularConstraint = null;
            mHorizontalBias = 0.5f;
            mVerticalBias = 0.5f;
            mMarginLeftGone = 0;
            mMarginRightGone = 0;
            mMarginStartGone = 0;
            mMarginEndGone = 0;
            mMarginTopGone = 0;
            mMarginBottomGone = 0;
        }
        return this;
    }

    private ConstraintWidget getTarget(Object target) {
        if (target instanceof Reference) {
            Reference referenceTarget = (Reference) target;
            return referenceTarget.getConstraintWidget();
        }
        return null;
    }

    private void applyConnection(ConstraintWidget widget,
            Object opaqueTarget,
            State.Constraint type) {
        ConstraintWidget target = getTarget(opaqueTarget);
        if (target == null) {
            return;
        }
        switch (type) {
            // TODO: apply RTL
            default:
                break;
        }
        switch (type) {
            case START_TO_START: {
                widget.getAnchor(ConstraintAnchor.Type.LEFT).connect(target.getAnchor(
                        ConstraintAnchor.Type.LEFT), mMarginStart, mMarginStartGone, false);
            }
            break;
            case START_TO_END: {
                widget.getAnchor(ConstraintAnchor.Type.LEFT).connect(target.getAnchor(
                        ConstraintAnchor.Type.RIGHT), mMarginStart, mMarginStartGone, false);
            }
            break;
            case END_TO_START: {
                widget.getAnchor(ConstraintAnchor.Type.RIGHT).connect(target.getAnchor(
                        ConstraintAnchor.Type.LEFT), mMarginEnd, mMarginEndGone, false);
            }
            break;
            case END_TO_END: {
                widget.getAnchor(ConstraintAnchor.Type.RIGHT).connect(target.getAnchor(
                        ConstraintAnchor.Type.RIGHT), mMarginEnd, mMarginEndGone, false);
            }
            break;
            case LEFT_TO_LEFT: {
                widget.getAnchor(ConstraintAnchor.Type.LEFT).connect(target.getAnchor(
                        ConstraintAnchor.Type.LEFT), mMarginLeft, mMarginLeftGone, false);
            }
            break;
            case LEFT_TO_RIGHT: {
                widget.getAnchor(ConstraintAnchor.Type.LEFT).connect(target.getAnchor(
                        ConstraintAnchor.Type.RIGHT), mMarginLeft, mMarginLeftGone, false);
            }
            break;
            case RIGHT_TO_LEFT: {
                widget.getAnchor(ConstraintAnchor.Type.RIGHT).connect(target.getAnchor(
                        ConstraintAnchor.Type.LEFT), mMarginRight, mMarginRightGone, false);
            }
            break;
            case RIGHT_TO_RIGHT: {
                widget.getAnchor(ConstraintAnchor.Type.RIGHT).connect(target.getAnchor(
                        ConstraintAnchor.Type.RIGHT), mMarginRight, mMarginRightGone, false);
            }
            break;
            case TOP_TO_TOP: {
                widget.getAnchor(ConstraintAnchor.Type.TOP).connect(target.getAnchor(
                        ConstraintAnchor.Type.TOP), mMarginTop, mMarginTopGone, false);
            }
            break;
            case TOP_TO_BOTTOM: {
                widget.getAnchor(ConstraintAnchor.Type.TOP).connect(target.getAnchor(
                        ConstraintAnchor.Type.BOTTOM), mMarginTop, mMarginTopGone, false);
            }
            break;
            case BOTTOM_TO_TOP: {
                widget.getAnchor(ConstraintAnchor.Type.BOTTOM).connect(target.getAnchor(
                        ConstraintAnchor.Type.TOP), mMarginBottom, mMarginBottomGone, false);
            }
            break;
            case BOTTOM_TO_BOTTOM: {
                widget.getAnchor(ConstraintAnchor.Type.BOTTOM).connect(target.getAnchor(
                        ConstraintAnchor.Type.BOTTOM), mMarginBottom, mMarginBottomGone, false);
            }
            break;
            case BASELINE_TO_BASELINE: {
                widget.immediateConnect(ConstraintAnchor.Type.BASELINE, target,
                        ConstraintAnchor.Type.BASELINE, mMarginBaseline, mMarginBaselineGone);
            }
            break;
            case BASELINE_TO_TOP: {
                widget.immediateConnect(ConstraintAnchor.Type.BASELINE,
                        target, ConstraintAnchor.Type.TOP, mMarginBaseline, mMarginBaselineGone);
            }
            break;
            case BASELINE_TO_BOTTOM: {
                widget.immediateConnect(ConstraintAnchor.Type.BASELINE, target,
                        ConstraintAnchor.Type.BOTTOM, mMarginBaseline, mMarginBaselineGone);
            }
            break;
            case CIRCULAR_CONSTRAINT: {
                widget.connectCircularConstraint(target, mCircularAngle, (int) mCircularDistance);
            }
            break;
            default:
                break;
        }
    }

    /**
     * @TODO: add description
     */
    public void apply() {
        if (mConstraintWidget == null) {
            return;
        }
        if (mFacade != null) {
            mFacade.apply();
        }
        mHorizontalDimension.apply(mState, mConstraintWidget, HORIZONTAL);
        mVerticalDimension.apply(mState, mConstraintWidget, VERTICAL);
        dereference();

        applyConnection(mConstraintWidget, mLeftToLeft, State.Constraint.LEFT_TO_LEFT);
        applyConnection(mConstraintWidget, mLeftToRight, State.Constraint.LEFT_TO_RIGHT);
        applyConnection(mConstraintWidget, mRightToLeft, State.Constraint.RIGHT_TO_LEFT);
        applyConnection(mConstraintWidget, mRightToRight, State.Constraint.RIGHT_TO_RIGHT);
        applyConnection(mConstraintWidget, mStartToStart, State.Constraint.START_TO_START);
        applyConnection(mConstraintWidget, mStartToEnd, State.Constraint.START_TO_END);
        applyConnection(mConstraintWidget, mEndToStart, State.Constraint.END_TO_START);
        applyConnection(mConstraintWidget, mEndToEnd, State.Constraint.END_TO_END);
        applyConnection(mConstraintWidget, mTopToTop, State.Constraint.TOP_TO_TOP);
        applyConnection(mConstraintWidget, mTopToBottom, State.Constraint.TOP_TO_BOTTOM);
        applyConnection(mConstraintWidget, mBottomToTop, State.Constraint.BOTTOM_TO_TOP);
        applyConnection(mConstraintWidget, mBottomToBottom, State.Constraint.BOTTOM_TO_BOTTOM);
        applyConnection(mConstraintWidget, mBaselineToBaseline,
                State.Constraint.BASELINE_TO_BASELINE);
        applyConnection(mConstraintWidget, mBaselineToTop, State.Constraint.BASELINE_TO_TOP);
        applyConnection(mConstraintWidget, mBaselineToBottom, State.Constraint.BASELINE_TO_BOTTOM);
        applyConnection(mConstraintWidget, mCircularConstraint,
                State.Constraint.CIRCULAR_CONSTRAINT);

        if (mHorizontalChainStyle != ConstraintWidget.CHAIN_SPREAD) {
            mConstraintWidget.setHorizontalChainStyle(mHorizontalChainStyle);
        }
        if (mVerticalChainStyle != ConstraintWidget.CHAIN_SPREAD) {
            mConstraintWidget.setVerticalChainStyle(mVerticalChainStyle);
        }
        if (mHorizontalChainWeight != UNKNOWN) {
            mConstraintWidget.setHorizontalWeight(mHorizontalChainWeight);
        }
        if (mVerticalChainWeight != UNKNOWN) {
            mConstraintWidget.setVerticalWeight(mVerticalChainWeight);
        }

        mConstraintWidget.setHorizontalBiasPercent(mHorizontalBias);
        mConstraintWidget.setVerticalBiasPercent(mVerticalBias);

        mConstraintWidget.frame.pivotX = mPivotX;
        mConstraintWidget.frame.pivotY = mPivotY;
        mConstraintWidget.frame.rotationX = mRotationX;
        mConstraintWidget.frame.rotationY = mRotationY;
        mConstraintWidget.frame.rotationZ = mRotationZ;
        mConstraintWidget.frame.translationX = mTranslationX;
        mConstraintWidget.frame.translationY = mTranslationY;
        mConstraintWidget.frame.translationZ = mTranslationZ;
        mConstraintWidget.frame.scaleX = mScaleX;
        mConstraintWidget.frame.scaleY = mScaleY;
        mConstraintWidget.frame.alpha = mAlpha;
        mConstraintWidget.frame.visibility = mVisibility;
        mConstraintWidget.setVisibility(mVisibility);
        mConstraintWidget.frame.setMotionAttributes(mMotionProperties);
        if (mCustomColors != null) {
            for (String key : mCustomColors.keySet()) {
                Integer color = mCustomColors.get(key);
                mConstraintWidget.frame.setCustomAttribute(key,
                        TypedValues.Custom.TYPE_COLOR, color);
            }
        }
        if (mCustomFloats != null) {
            for (String key : mCustomFloats.keySet()) {
                float value = mCustomFloats.get(key);
                mConstraintWidget.frame.setCustomAttribute(key,
                        TypedValues.Custom.TYPE_FLOAT, value);
            }
        }
    }
}