I have written the following method. It dynamically creates 16 red view boxes, and then adds them to a constraint layout chain in order to distribute them horizontally across the parent layout. It works, but only if I give the views a specific width value, and I want them to fill the available space. If I set each view's width to ConstraintSet.MATCH_CONSTRAINT
, none of them appear at all.
What am I doing wrong? I thought if the width was set to MATCH_CONSTRAINT
, each view would fill up the space allotted to it by its weight value. Instead, they aren't appearing at all, and they only show up if I give them a specific width but then they won't grow or shrink to fit the view. It's as if setting them to MATCH_CONSTRAINT
is the same as setting the width literally to zero.
private fun createDropTargets(parentView: ConstraintLayout) {
parentView.setOnDragListener(StaffDragListener())
val set = ConstraintSet()
val ids = arrayListOf<Int>()
val weights = arrayListOf<Float>()
for (i in 0..15) {
val drop = View(activity)
drop.setBackgroundColor(Color.RED)
// THE NEXT LINE IS WHERE I SET THE WIDTH VALUE. IF I SET TO A NUMBER > 0 THE VIEWS SHOW UP, BUT DO NOT DYNAMICALLY FILL THE SPACE
val params = ConstraintLayout.LayoutParams(ConstraintSet.MATCH_CONSTRAINT, 0)
params.setMargins(5, 0, 5, 0)
drop.layoutParams = params
drop.id = View.generateViewId()
parentView.addView(drop)
ids.add(drop.id)
weights.add(1f)
}
set.clone(parentView)
var previousId: Int? = null
for ((index, id) in ids.withIndex()) {
if (previousId == null) {
set.connect(id, ConstraintSet.LEFT, ConstraintSet.PARENT_ID, ConstraintSet.LEFT)
} else {
set.connect(id, ConstraintSet.LEFT, previousId, ConstraintSet.RIGHT)
if (index == ids.size - 1) {
set.connect(id, ConstraintSet.RIGHT, ConstraintSet.PARENT_ID, ConstraintSet.RIGHT)
}
}
previousId = id
}
set.createHorizontalChain(ConstraintSet.PARENT_ID, ConstraintSet.LEFT, ConstraintSet.PARENT_ID, ConstraintSet.RIGHT, ids.toIntArray(), weights.toFloatArray(), ConstraintSet.CHAIN_SPREAD_INSIDE)
set.applyTo(parentView)
}
MATCH_CONSTRAINT
is setting the width/height to zero because it is defined as follows in ConstraintSet:
public static final int MATCH_CONSTRAINT = 0;
What this says is that the constraints will define the size. No contraints, or improper constraints, will just result in a zero width/height.
Your code is correct except that the height is set to MATCH_CONSTRAINT
(remember 0 == MATCH_CONSTRAINT
) but you do not apply constraints to the height so the views just disappear (width but no height.) If you supply a set height to the views, they will appear. The following code will show the views with a height of 100px:
private fun createDropTargets(parentView: ConstraintLayout) {
parentView.setOnDragListener(StaffDragListener())
val set = ConstraintSet()
val ids = arrayListOf<Int>()
val weights = arrayListOf<Float>()
for (i in 0..15) {
val drop = View(activity)
drop.setBackgroundColor(Color.RED)
val params = ConstraintLayout.LayoutParams(ConstraintSet.MATCH_CONSTRAINT, 100)
params.setMargins(5, 0, 5, 0)
drop.layoutParams = params
drop.id = View.generateViewId()
parentView.addView(drop)
ids.add(drop.id)
weights.add(1f)
}
set.clone(parentView)
set.createHorizontalChain(ConstraintSet.PARENT_ID, ConstraintSet.LEFT, ConstraintSet.PARENT_ID, ConstraintSet.RIGHT, ids.toIntArray(), weights.toFloatArray(), ConstraintSet.CHAIN_SPREAD_INSIDE)
set.applyTo(parentView)
}
By the way, the second loop is redundant. All that work is accomplished with the creation of the chain.
You will have to decide if you want a defined height or if you will let the height be set by the appropriate constraints applied in the vertical direction.