#android-constraintlayout
#android-constraintlayout
Вопрос:
Я написал следующий метод. Он динамически создает 16 красных полей просмотра, а затем добавляет их в цепочку компоновки ограничений, чтобы распределить их по горизонтали по родительскому макету. Это работает, но только если я задаю представлениям определенное значение ширины и хочу, чтобы они заполняли доступное пространство. Если я установлю ширину каждого представления ConstraintSet.MATCH_CONSTRAINT
, ни один из них не появится вообще.
Что я делаю не так? Я думал, что если бы была установлена ширина MATCH_CONSTRAINT
, каждое представление заполняло бы отведенное ему пространство по его значению веса. Вместо этого они вообще не отображаются, и они отображаются только в том случае, если я задаю им определенную ширину, но тогда они не будут увеличиваться или уменьшаться, чтобы соответствовать представлению. Это как если бы их установка MATCH_CONSTRAINT
была такой же, как установка ширины буквально равной нулю.
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)
}
Ответ №1:
MATCH_CONSTRAINT
устанавливает ширину / высоту равными нулю, поскольку она определена следующим образом в ConstraintSet:
public static final int MATCH_CONSTRAINT = 0;
Это говорит о том, что ограничения будут определять размер. Отсутствие ограничений или неправильных ограничений просто приведет к нулевой ширине / высоте.
Ваш код правильный, за исключением того, что для высоты установлено значение MATCH_CONSTRAINT
(помните 0 == MATCH_CONSTRAINT
), но вы не применяете ограничения к высоте, поэтому представления просто исчезают (ширина, но нет высоты.) Если вы зададите заданную высоту для представлений, они появятся. Следующий код покажет представления высотой 100 пикселей:
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)
}
Кстати, второй цикл является избыточным. Вся эта работа выполняется с созданием цепочки.
Вам нужно будет решить, хотите ли вы определенную высоту или позволите установить высоту с помощью соответствующих ограничений, применяемых в вертикальном направлении.