Search code examples
javaandroidandroid-layoutandroid-listviewandroid-scrollview

Changing orientation removes UI elements


When the phone is in portrait mode, it shows the title and image at the top and below that there's the button and ListView with comments. However when I turn the phone to be in landscape mode, the button and ListView dissapear and only the title and image are shown. I basically can't scroll below the image anymore.

There is a third element -- a TextView for the body -- that is also inside that ScrollView: each layout will either have that TextView with content or an image. The same thing happens when it's the TextView that has content and no image. This does not occur when the image or text don't take up the entire screen though.

Portrait mode:

enter image description here

Landscape mode:

enter image description here

Accompanying code:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="net.vannevel.redditapp.activities.PostActivity">

    <TextView
        android:id="@+id/postDetailTitle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:textColor="#000" />

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <ImageView
                android:id="@+id/postDetailImage"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />

            <TextView
                android:id="@+id/postDetailBody"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
        </LinearLayout>
    </ScrollView>

    <Button
        android:id="@+id/postDetailViewOnlineButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="onViewOnlineButtonClicked"
        android:text="View original source" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="COMMENTS" />

    <ListView
        android:id="@+id/postDetailCommentList"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

Solution

  • So your problem is that the items you have inside the scroll view are taller than the screen height in landscape. Even if you scroll inside the ScrollView, there's nothing you can do once you get to the end of it. All the elements placed outside the ScrollView are going to be off screen and placed outside any scrollable container.

    I can see 3 possible solutions:

    1 - set fixed size to the scroll view so that it doesn't occupy the whole screen, so that you let the other views in. Not practical, however: phone in landscape means short height and you have to fit a picture and list with comments...

    2 - have a different layout for landscape - picture on left, list with comments on right

    3 - get rid of the ScrollView and set everything above the ListView as a ListView header (addHeaderView) For example:

    Step 1 - extract everything you have on top of the ListView and put it into a different layout file - let's call it header.xml

    Step 2 - inflate the layout:

    View headerView = inflater.inflate(R.layout.header, listView, false);
    

    Step 3 - initialize the items on the header just like you do it now

    Step 4 - set the view as the header of the list ListView:

    listView.addHeaderView(headerView, null, false);
    

    The side effect of this approach is that the header, being part of the ListView now, it will scroll as you scroll the list. Also, it will offset your position in the adapter by 1.