Constraint layout is by far one of the most versatile ViewGroups in the Android framework, However, the Kotlin code needed to update the constraints of a view programmatically can be a bit wordy. I have created a Constraint Layout Kotlin Extension that will make that process much easier to apply and cleaner to look at in code. Let’s get started!
Here we have the ConstraintInstructions interface that has two simple implementations, ConnectConstraint and DisconnectConstraint.
ConnectConstraints takes 4 parameters that help describe the view you're looking to constrain and to what.
- startID — the resourceId of the view your looking to constrain.
- startSide — the side of the view passed as startID that you want to constrain. The values passed into the *side parameters should be constants from the ConstraintSet class. Common one are : ConstraintSet.START, ConstraintSet.TOP, ConstraintSet.END, or ConstraintSet.Bottom.
- endID — the resourceId of the view your looking to constrain to. Remember, usually, views are constrained to either another view or to parent, So if you want to constrain the startID view to another view, you would pass in the resourceId of that view. If you want to constrain to the parent, then pass in 0.
- endSide — the side of the view passed as endID that you want to constrain the startID view to.
DisconnectConstraint only has 2 parameters that describe the view and the constrained side of that view to clear.
- startID — the resourceId of the view your looking to remove a constraint from.
- startSide — the side of the view passed as startID that you want to remove a constraint from. This follows the same pattern as before by only corresponding to constants in the ConstraintSet class.
For better understanding, let’s see an example.
In XML, to constrain, we describe the sides and the view/parent to attach to. In the ImageView we apply app:layout_constraintTop_toBottomOf=”@id/title”, which is the same as saying;
This should read very similarly; The only thing that isn’t mentioned in XML is the view reference for startID because it’s the view we are applying the attribute to.
The Extension that puts it all together
Here we have an extension function that accepts a list of ContraintInstuctions and applies them to the child views of a ConstraintLayout. We start by creating a ConstriantSet Object and clone() the current constraints of the layout. Then we iterate through the instructions and match on class type. Whenever we want to connect constraints, we use the ConstraintSet function connect(); which accepts the same parameters we have in ConnectConstraint. If instead, we want to remove constraints from a view, we use the ConstraintSet function clear() and pass the same parameter in DisconnectConstraint. Lastly, we apply the new ConstraintSet changes to the layout and BOOM! We can quickly and neatly connect and disconnect constraints programmatically.