2

I would like to change the app:layout_constraintTop_toBottomOf of an element at runtime. I tried to solve it using this question/answers:

Android : How to programmatically set layout_constraintRight_toRightOf "parent"

Unfortunately my element is a RelativeLayout, so it can not be cast to ConstraintLayout, like in this answer with constraintSet

Then I tried to solve it based on this answer with LayoutParams, but RelativeLayout.LayoutParams has no property like toBottomOf.

The layout looks like this:

<RelativeLayout
    android:id="@+id/myElement"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="24dp"
    android:layout_marginTop="24dp"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/otherElement">
    
    <!-- Child elements -->
    
</RelativeLayout>
Iter Ator
  • 8,226
  • 20
  • 73
  • 164
  • can you show some code? – Piyush Maheswari Dec 08 '20 at 14:40
  • @PiyushMaheswari I just tried to use the ones in the linked answers. The first one failed at `ConstraintLayout constraintLayout = (ConstraintLayout)findViewById(R.id.myElement)` and in the second case I am not able to find the needed attribute. – Iter Ator Dec 08 '20 at 14:44
  • Please provide us with the XML code of your layout – Grigorii Raudiiainen Dec 08 '20 at 14:53
  • @GrigoriiRaudiiainen I updated the question with the XML – Iter Ator Dec 08 '20 at 14:59
  • That's not enough to find the root cause of an issue. If you're trying to change the constraint of the RelativeLayout with id `myElement` we need make sure that the parent of that layout is indeed `ConstraintLayout`, otherwise that's meaningless. If you're trying to change constraints of the child of RelativeLayout, then that's impossible because this attributes have no affect inside of RelativeLayout Constraint of what view are you trying to change and what is the parent of that view in layout? – Grigorii Raudiiainen Dec 08 '20 at 15:48
  • @GrigoriiRaudiiainen The parent of that `myElement ` is the root element `androidx.constraintlayout.widget.ConstraintLayout`. The referenced `otherElement` is an `ImageButton` – Iter Ator Dec 08 '20 at 17:11

1 Answers1

3

In order to change app:layout_constraintTop_toBottomOf attribute of your RelativeLayout in the runtime, you can do one of the following:

  1. Clone ConstraintSet of the ConstraintLayout, that is the parent view of your RelativeLayout. Update the constraint in the cloned ConstraintSet and then apply the ConstraintSet back to the ConstraintLayout.

Sample code:

//ConstraintLayout constraintLayout = findViewById<View>(R.id.myElement).getParent()
constraintSet = new ConstraintSet();
constraintSet.clone(constraintLayout); 
constraintSet.connect(R.id.myElement, ConstraintSet.TOP, [other element Id], ConstraintSet.BOTTOM);
constraintSet.applyTo(constraintLayout);

Please Note: You should pass ConstraintLayout to the ConstraintSet.clone() method, not the RelativeLayout.

  1. Modify LayoutParams of myElement view!

Like that:

//RelativeLayout myElement = findViewById<RelativeLayout>(R.id.myElement)
LayoutParams layoutParams = (LayoutParams) myElement.getLayoutParams();
layoutParams.topToBottom = [id of the another view];
myElement.setLayoutParams(layoutParams);

In that case, if the parent of myElement is ConstraintLayout you'll get ConstraintLayout.LayoutParams class in myElement.getLayoutParams(); that have property topToBottom.

  • I tried the second one, but I get this error: `android.widget.RelativeLayout$LayoutParams cannot be cast to androidx.constraintlayout.widget.ConstraintLayout$LayoutParams` – Iter Ator Dec 08 '20 at 20:48
  • @IterAtor The RelativeLayout itself should have ConstraintLayout.LayoutParams. Are you sure you're trying to get params out of the correct view? Can you please show us some code, how do you do that? – Grigorii Raudiiainen Dec 09 '20 at 19:58
  • Perfectly working. – Omer123 Jul 08 '22 at 12:48