Search code examples
javaandroidxmlandroid-layoutrotation

How to constrain a rotated View/Button to the left side of ConstraintLayout on Android?


Edit: it is possible to just to use translateX (see comments and accepted answer). I don't know how I missed that.

On Android, I want to rotate a simple button 90 degrees and have it stick against the left side of my ConstraintLayout. However, when I try this, there remains significant space between the left side of the screen and the button. This is what it should look like:

desired outcome

This is my XML layout file:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:rotation="90"
        android:text="My example button"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

And here is the Android Studio design view of what it actually looks like:

wrong outcome

This seems to be because the constraints to the left/start (and top and bottom) are applied first, and the rotation second. I have tried programmatically to fix this problem to no avail in Java:

Button button = view.findViewById(R.id.button);
button.setRotation(90); // already done, but doesn't matter

// constrain to left side after after rotation (doesn't help)
ConstraintSet constraintSet = new ConstraintSet();
constraintSet.clone((ConstraintLayout) view);
constraintSet.connect(button.getId(), ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START);
constraintSet.applyTo((ConstraintLayout) view);

// attempt to fix positioning with margins (doesn't move anything at all)
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) btnTest.getLayoutParams();
params.setMargins(-100, 0, 0, -100); // left, top, right, bottom
btnTest.setLayoutParams(params);

I also tried changing the margins in the XML layout file, which similarly has absolutely no effect. Edit: it seems like using negative margins didn't work in my original project, but it does in a newer test project. I suspect this is caused by using old versions of some libraries (probably the material library which I'm implicitly using through appcompat 1.1.0).

Does anyone know how to achieve the result I want?

Thanks for your help!


Solution

  • Contrary to your statement, margin works for me:

    <button
          android:id="@+id/button"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_marginLeft="-65dp"
          android:rotation="90"
          android:text="My example button"
          app:layout_constraintBottom_toBottomOf="parent"
          app:layout_constraintStart_toStartOf="parent"
          app:layout_constraintTop_toTopOf="parent" />
    

    If you want to make the shift programmatically, the following solution also works for me:

    button.setTranslationX(-195f);  // in pixels
    

    Third possibility: See this older solution.