9

I have several nested layouts that I'm trying to rotate 90 degrees on demand in code. I've got the setRotation part of things working just fine, but unfortunately things aren't resizing quite right with the rotation. The width on these elements is set to match_parent, and after the rotation it's still matching the parent width, not the parent height that it should be matching.

XML

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/mainLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="link.basiclifecounter.LifeCounter"
    android:background="#CC00CC">

    <LinearLayout
        android:id="@+id/topPlayers"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="2"
        android:orientation="vertical"
        android:background="#CC0000">

        <RelativeLayout
            android:id="@+id/p3"
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1">

        **A bunch of stuff in here**

        </RelativeLayout>

        <RelativeLayout
            android:id="@+id/p2"
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1">

        **A bunch of stuff in here**

        </RelativeLayout>
    </LinearLayout>

    <LinearLayout
        android:id="@+id/bottomPlayer"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="vertical"
        android:background="#00CC00">

        <RelativeLayout
            android:id="@+id/p1"
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1">

        **A bunch of stuff in here**

        </RelativeLayout>
    </LinearLayout>
</LinearLayout>

Rotation Java Code

view.findViewById(R.id.topPlayers).setRotation(90); //Rotate the entire top box
view.findViewById(R.id.p3).setRotation(180); //Flip one side so both players face outwards

This picture shows the image before the rotation occurs.

This picture shows the image after the rotation occurs.

As you can see, the entire box has been rotated after it's height and width are already set. In the unrotated version the width (match_parent) should be full screen and the height (layout_weight=2) should be 2/3rds of the screen. That works just fine. The problem is after it rotates, those sizes stay the same instead of adapting and changing to the new rotation.

I threw in some bright background colors to help troubleshoot, that Pink that you're seeing is in the main LinearLayout, not in any of the layouts that are rotated.

I did try including the rotation in the xml itself, instead of within the code, and got the exact same results as the after picture, so it's clearly something I don't understand about how to get the layout widths the way I want. Can I just not use layout_weight effectively with rotation?

Jeff McAleer
  • 354
  • 2
  • 12
  • For what it's worth I never did solve this. I ended up creating separate XML files for with and without the rotation and using a custom VerticalTextView as suggested [here](http://stackoverflow.com/questions/1258275/vertical-rotated-label-in-android) to get my text to rotate. Working like a charm, even if the multiple xml files is a little clunkier than a simple rotation would've been. – Jeff McAleer Sep 27 '15 at 02:26
  • I don't (yet) have a pretty answer, but I think this can be achieved by getting the dimensions of the view's parent and setting the view's dimensions to match. I.e., `int width = ((View) myView.getParent()).getWidth();`, `myView.setLayoutParams(new FrameLayout.LayoutParams(width, height));`. I'm having some issues with the position, though, but I think I can overcome those with some combination of `setPivotX()` and `setX()`. – VinceFior Jan 14 '16 at 03:45
  • Swap the height and weight values of layout parameters and reset the layout params of the view when you rotate it. – Jayakrishnan Jun 13 '17 at 13:01

1 Answers1

1

I think that you are having the same issue as outlined in this Stack Overflow question. It appears that the rotation is simply not taken into account for layout purposes. In other words, layout occurs then the rotation happens with the views as laid out prior to rotation.

This answer to that same question may help you.

You could also manually adjust the measurements. Either way is a little messy, but I think that is the way it is.


You could load an alternate layout that will behave as you wish instead of doing the rotation. (See layout and image below.) You can also be achieve the same result by changing the layout parameters programmatically.

Here is a project on GitHub that demonstrates doing the rotation programmatically. The view rotates after a three second pause.

I hope that you find this useful.

enter image description here

alternate.xml

    <LinearLayout
        android:id="@+id/topPlayers"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="2"
        android:background="#CC0000"
        android:orientation="horizontal">

        <RelativeLayout
            android:id="@+id/p3"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:orientation="vertical"
            android:rotation="90">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="p3"
                android:textSize="48sp" />
        </RelativeLayout>

        <RelativeLayout
            android:id="@+id/p2"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="#0000CC"
            android:gravity="center"
            android:orientation="vertical">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:rotation="-90"
                android:text="p2"
                android:textSize="48sp" />
        </RelativeLayout>
    </LinearLayout>

    <LinearLayout
        android:id="@+id/bottomPlayer"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="#00CC00"
        android:orientation="vertical">

        <RelativeLayout
            android:id="@+id/p1"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:gravity="center"
            android:orientation="vertical">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="p1"
                android:textSize="48sp" />
        </RelativeLayout>
    </LinearLayout>

Cheticamp
  • 61,413
  • 10
  • 78
  • 131