66

I have a view in ConstrainLayout as follows.

<TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:maxWidth="260dp"
        android:textColor="#FFF"
        android:textSize="16sp"
        app:layout_constraintLeft_toLeftOf="@+id/parent"
        app:layout_constraintTop_toBottomOf="@id/message_date"
        android:id="@+id/text_main"
        />

I would like to change the view to either app:layout_constraintLeft_toLeftOf="@+id/parent" or layout_constraintLeft_toRightOf="@+id/parent" programmatically in recycleViewHolder based on some conditions.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Relm
  • 7,923
  • 18
  • 66
  • 113
  • Possible duplicate of [Add view to constraintLayout with constraints similar to another child](http://stackoverflow.com/questions/39831710/add-view-to-constraintlayout-with-constraints-similar-to-another-child) – W4R10CK Jan 16 '17 at 06:36
  • 1
    @W4R10CK I don't want to add a view, I just want to change alignment. Can you post the relevant part of that answer? – Relm Jan 16 '17 at 07:08

5 Answers5

97

Here is an example of setting a button to the bottom of parent view using java code:

ConstraintLayout constraintLayout;
ConstraintSet constraintSet;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    constraintLayout = (ConstraintLayout) findViewById(R.id.activity_main_constraint_layout);

    Button button = new Button(this);
    button.setText("Hello");
    constraintLayout.addView(button);

    constraintSet = new ConstraintSet();
    constraintSet.clone(constraintLayout);

    constraintSet.connect(button.getId(), ConstraintSet.LEFT, constraintLayout.getId(), ConstraintSet.RIGHT, 0);
    constraintSet.constrainDefaultHeight(button.getId(), 200);
    constraintSet.applyTo(constraintLayout);

}

to achieve something like this,

app:layout_constraintLeft_toLeftOf="@+id/parent" 

your java code should look like this

set.connect(YOURVIEW.getId(),ConstraintSet.LEFT,ConstraintSet.PARENT_ID,ConstraintSet.LEFT,0);

and to achieve something like this,

layout_constraintLeft_toRightOf="@+id/parent"

your java code should look like this,

set.connect(YOURVIEW.getId(),ConstraintSet.LEFT,ConstraintSet.PARENT_ID,ConstraintSet.RIGHT,0);

Here, I'm assuming android:id="@+id/parent" is the id of your parent ConstraintLayout .

Micho
  • 3,929
  • 13
  • 37
  • 40
Darshan Soni
  • 1,779
  • 1
  • 12
  • 24
  • 1
    `set.applyTo(layout);` doesn't this apply these constraints to the parent instead of the `TextView`? Should it be ? `set.applyTo(button);` or something similar? – Relm Jan 16 '17 at 09:37
  • 1
    No the set knows to whom you want to apply the changes now it's time to tell the parent layout, hey please apply this changes. so this should be like set.applyTo(parent). – Darshan Soni Jan 17 '17 at 12:53
  • 1
    Your code is wrong, first you have to add button in constraint layout then constraintSet.clone(constraintLayout); will be done. Otherwise nothing is done to button – Khyati Vara Jun 05 '17 at 04:53
17

constraintSet = new ConstraintSet(); and so on

Did not work for me anyhow.

Solved by

  LayoutParams layoutParams = (LayoutParams) viewToChange.getLayoutParams();
    layoutParams.leftToLeft = anotherViewId;
    layoutParams.rightToRight =anotherViewId;
    layoutParams.topToTop = anotherViewId;
    layoutParams.bottomToBottom = anotherViewId;
    layoutParams.startToStart =anotherViewId;
    layoutParams.endToEnd = anotherViewId;
    viewToChange.setLayoutParams(layoutParams);
Holiday Fun
  • 385
  • 3
  • 7
5

Use id

class MyLayout(context: Context) : ConstraintLayout(context) {

    fun show() {
        val view = ImageView(context)
        addView(view)
        val params = view.layoutParams as ConstraintLayout.LayoutParams
        params.height = 100 
        params.width = 50
        params.rightToRight = id
        view.requestLayout()
    }
}
onmyway133
  • 45,645
  • 31
  • 257
  • 263
3

I had same situation when I needed to move buttons down once a new EditText appears, In XML file they had constraints like this:

app:layout_constraintTop_toBottomOf="@+id/first_layout"

and what I needed to do is changing to sth like programmatically:

app:layout_constraintTop_toBottomOf="@+id/second_layout"

Using ConstraintLayout.LayoutParams the task is pretty straightforward e.g.

Kotlin:

val currentLayout = btn.layoutParams as ConstraintLayout.LayoutParams // btn is a View here
currentLayout.topToBottom = R.id.second_layout // resource ID of new parent field
btn.layoutParams = currentLayout

and that's it!

dsounded
  • 703
  • 5
  • 21
2

Haven't seen better solution than this:

textMain.updateLayoutParams<ConstraintLayout.LayoutParams> {
    startToEnd = anyOtherView.id
    topToTop = anyOtherView.id
    endToStart = anyOtherView.id
    bottomToBottom = anyOtherView.id
  }
Andrey Kijonok
  • 291
  • 2
  • 17