Search code examples
androidlistviewandroid-custom-viewcustom-adapter

TextView in custom ListView item view isn't filling parent in API 18 & 19


I have a custom list view adaptor that uses a customized list item view. The custom list item view has an image view on the left with a stack of two TextViews, a main title on top and subtitle below, to the right. What I want to happen is to have the subtitle disappear and the main text to fill the space if there is no subtext to display.

I've tested this against all other phone / tablet APIs between 16 and 23. Everything is working as expected EXCEPT when I run on a device running with Android 4.3.1 (API 18) Android 4.4.2 (API 19). Running against API 18 or 19, the subtitle view visibility does get set to View.GONE, but the main title view does not resize to occupy the space.

Does anyone know what's going on here?

Here's the layout file for the list item:

list_item.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:padding="5dp">

    <ImageView
        android:id="@+id/list_item_snapshot_imageview"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@color/medium_grey"
        android:contentDescription="@string/item_snapshot" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignBottom="@id/list_item_snapshot_imageview"
        android:layout_alignTop="@id/list_item_snapshot_imageview"
        android:layout_marginLeft="5dp"
        android:layout_marginStart="5dp"
        android:layout_toEndOf="@id/list_item_snapshot_imageview"
        android:layout_toRightOf="@id/list_item_snapshot_imageview"
        android:orientation="vertical">

        <TextView
            android:id="@+id/list_item_title_textview"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:gravity="center_vertical"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:textSize="20sp"
            tools:text="Main Text" />

        <TextView
            android:id="@+id/list_item_subtitle_textview"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:gravity="center_vertical"
            android:textAppearance="?android:attr/textAppearanceSmall"
            android:textSize="14sp"
            tools:text="Subtext" />
    </LinearLayout>
</RelativeLayout>

Here's the java code that is responsible for updating the content. viewHolder is just a static class containing references to the TextViews and is held in a tag on the list item for view recycling.

NamedItem item = getRowItem(section, position);
if (item != null) {
    viewHolder.titleTextView.setText(item.getName());

    if (item.getSubtitle() != null) {
        String subtitle = ((ItemInfo) item).getSubtitle();
        viewHolder.subtitleTextView.setText(subtitle);
        viewHolder.subtitleTextView.setVisibility(View.VISIBLE);
    } else {
        viewHolder.subtitleTextView.setVisibility(View.GONE);
    }
}

EDIT I did some more testing and this also is happening on API 18 as well as 19. I changed the rest of the description to reflect that.


Solution

  • Figured this out. Looks like something about the way ListView item views are handled in API 18 & 19 doesn't like having RelativeLayout as the root layout in a custom ListView item. Wrapping the entire layout in a LinearLayout fixed the problem:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:padding="5dp">
    
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
            <!-- Other Views ... -->
    
        </RelativeLayout>
    </LinearLayout>
    

    Tried this after coming across this SO answer: https://stackoverflow.com/a/21334982/1777839

    Still doesn't explain WHY this happens though.