我需要帮助ConstraintSet。我的目标是在代码中改变视图的约束,但我不知道如何做到这一点。

我有4个textview和一个ImageView。我需要将ImageView约束设置为textview之一。

check_answer4 = (TextView) findViewById(R.id.check_answer4);
check_answer1 = (TextView) findViewById(R.id.check_answer1);
check_answer2 = (TextView) findViewById(R.id.check_answer2);
check_answer3 = (TextView) findViewById(R.id.check_answer3);

correct_answer_icon = (ImageView) findViewById(R.id.correct_answer_icon);

如果第一个答案是正确的,我需要设置ImageView的约束为

app:layout_constraintRight_toRightOf="@+id/check_answer1"
app:layout_constraintTop_toTopOf="@+id/check_answer1"

如果第二个答案是正确的,我需要设置ImageView的约束为

app:layout_constraintRight_toRightOf="@+id/check_answer2"
app:layout_constraintTop_toTopOf="@+id/check_answer2"

等等。


当前回答

To set constraints of image view to: app:layout_constraintRight_toRightOf="@+id/check_answer1" app:layout_constraintTop_toTopOf="@+id/check_answer1" use: ConstraintLayout constraintLayout = findViewById(R.id.parent_layout); ConstraintSet constraintSet = new ConstraintSet(); constraintSet.clone(constraintLayout); constraintSet.connect(R.id.imageView,ConstraintSet.RIGHT,R.id.check_answer1,ConstraintSet.RIGHT,0); constraintSet.connect(R.id.imageView,ConstraintSet.TOP,R.id.check_answer1,ConstraintSet.TOP,0); constraintSet.applyTo(constraintLayout); To set constraints of image view to: app:layout_constraintRight_toRightOf="@+id/check_answer2" app:layout_constraintTop_toTopOf="@+id/check_answer2" use: ConstraintLayout constraintLayout = findViewById(R.id.parent_layout); ConstraintSet constraintSet = new ConstraintSet(); constraintSet.clone(constraintLayout); constraintSet.connect(R.id.imageView,ConstraintSet.RIGHT,R.id.check_answer2,ConstraintSet.RIGHT,0); constraintSet.connect(R.id.imageView,ConstraintSet.TOP,R.id.check_answer2,ConstraintSet.TOP,0); constraintSet.applyTo(constraintLayout);

其他回答

To set constraints of image view to: app:layout_constraintRight_toRightOf="@+id/check_answer1" app:layout_constraintTop_toTopOf="@+id/check_answer1" use: ConstraintLayout constraintLayout = findViewById(R.id.parent_layout); ConstraintSet constraintSet = new ConstraintSet(); constraintSet.clone(constraintLayout); constraintSet.connect(R.id.imageView,ConstraintSet.RIGHT,R.id.check_answer1,ConstraintSet.RIGHT,0); constraintSet.connect(R.id.imageView,ConstraintSet.TOP,R.id.check_answer1,ConstraintSet.TOP,0); constraintSet.applyTo(constraintLayout); To set constraints of image view to: app:layout_constraintRight_toRightOf="@+id/check_answer2" app:layout_constraintTop_toTopOf="@+id/check_answer2" use: ConstraintLayout constraintLayout = findViewById(R.id.parent_layout); ConstraintSet constraintSet = new ConstraintSet(); constraintSet.clone(constraintLayout); constraintSet.connect(R.id.imageView,ConstraintSet.RIGHT,R.id.check_answer2,ConstraintSet.RIGHT,0); constraintSet.connect(R.id.imageView,ConstraintSet.TOP,R.id.check_answer2,ConstraintSet.TOP,0); constraintSet.applyTo(constraintLayout);

你也可以使用TransitionManager来动画化这些变化:

public static void animateConstraintLayout(ConstraintLayout constraintLayout, ConstraintSet set, long duration) {
    AutoTransition trans = new AutoTransition();
    trans.setDuration(duration);
    trans.setInterpolator(new AccelerateDecelerateInterpolator());

    TransitionManager.beginDelayedTransition(constraintLayout, trans);
    set.applyTo(constraintLayout);
}

你可以在用ConstraintSet更新布局后这样调用它:

ConstraintSet set = new ConstraintSet();
set.clone(constraintLayout);
set.connect(R.id.example, ConstraintSet.BOTTOM, R.id.anotherExample, ConstraintSet.BOTTOM);
set.connect(R.id.example, ConstraintSet.TOP, R.id.anotherExample, ConstraintSet.TOP);

animateConstraintLayout(constraintLayout, set, 500);

除了azizbekian的回答,让我指出两件事:

如果左/右都不行,试着这样开始/结束:

参数个数。startToEnd = button2.id

如果你想移除一个约束,使用UNSET标志,像这样:

参数个数。startToEnd = ConstraintLayout.LayoutParams.UNSET

另一种方法是像这样更新视图的布局参数(不请求layout):

yourView.updateLayoutParams<ConstraintLayout.LayoutParams> {
        startToEnd = targetView.id
        topToTop = targetView.id
        bottomToBottom = targetView.id
        //add other constraints if needed
      }

你可以用ConstraintSet或ConstraintLayout在ConstraintLayout中创建约束。LayoutParams属性。

为了方便使用,我创建了一个ConstraintSet kotlin扩展。 这是简单而健壮的。

使用

 applyConstraint {
            centerHorizontallyParent(imageView)
            centerHorizontallyParent(textView)
            topToParent(imageView, px(12))
            topToBottom(textView, imageView, px(4))
        }

Code

fun ConstraintLayout.applyConstraint(block: ConstraintSet.() -> Unit) {
    ConstraintSet().apply {
        clone(this@applyConstraint)
        block(this)
    }.applyTo(this)
}

fun ConstraintSet.centerParent(v1: View) {
    centerHorizontallyParent(v1)
    centerVerticallyParent(v1)
}

fun ConstraintSet.centerHorizontallyParent(v1: View) {
    centerHorizontally(v1.id, PARENT_ID)
}

fun ConstraintSet.centerVerticallyParent(v1: View) {
    centerVertically(v1.id, PARENT_ID)
}

fun ConstraintSet.topToTop(v1: View, v2: View, @Px margin: Int = 0) {
    connect(v1.id, TOP, v2.id, TOP, margin)
}

fun ConstraintSet.topToParent(v1: View, @Px margin: Int = 0) {
    connect(v1.id, TOP, PARENT_ID, TOP, margin)
}

fun ConstraintSet.bottomToBottom(v1: View, v2: View, @Px margin: Int = 0) {
    connect(v1.id, BOTTOM, v2.id, BOTTOM, margin)
}

fun ConstraintSet.bottomToParent(v1: View, @Px margin: Int = 0) {
    connect(v1.id, BOTTOM, PARENT_ID, BOTTOM, margin)
}

fun ConstraintSet.topToBottom(v1: View, v2: View, @Px margin: Int = 0) {
    connect(v1.id, TOP, v2.id, BOTTOM, margin)
}

fun ConstraintSet.bottomToTop(v1: View, v2: View, @Px margin: Int = 0) {
    connect(v1.id, BOTTOM, v2.id, TOP, margin)
}

fun ConstraintSet.startToStart(v1: View, v2: View, @Px margin: Int = 0) {
    connect(v1.id, START, v2.id, START, margin)
}

fun ConstraintSet.startToParent(v1: View, @Px margin: Int = 0) {
    connect(v1.id, START, PARENT_ID, START, margin)
}

fun ConstraintSet.endToEnd(v1: View, v2: View, @Px margin: Int = 0) {
    connect(v1.id, END, v2.id, END, margin)
}

fun ConstraintSet.endToParent(v1: View, @Px margin: Int = 0) {
    connect(v1.id, END, PARENT_ID, END, margin)
}

fun ConstraintSet.startToEnd(v1: View, v2: View, @Px margin: Int = 0) {
    connect(v1.id, START, v2.id, END, margin)
}

fun ConstraintSet.endToStart(v1: View, v2: View, @Px margin: Int = 0) {
    connect(v1.id, END, v2.id, START, margin)
}