Spinner with multi-line items overlaps selected item display on Froyo

Michael Alan Huff picture Michael Alan Huff · Apr 2, 2013 · Viewed 11.2k times · Source

I'm trying to create Spinners that look the same on all versions of Android back to Froyo. To that end, I'm using HoloEverywhere. Some of the spinner item text is more than one line, and I'd like it to wrap.

Using the default layout, android.R.layout.simple_spinner_dropdown_item, or HoloEverywhere's drop-in replacement for it, ellipsizes the text instead of wrapping it.

Taking the HoloEverywhere's layout as a starting point for a custom layout with singleLine set to false, ellipsize set to none, and layout_height set to wrap_content doesn't help, the text is still cut off.

I can get the text to wrap correctly in the dropdown by wrapping the TextView in a LinearLayout, but on Froyo devices this messes up the display of the selected item: Every time you can't get a uniform look  back to froyo jake wharton sheds a single tear.

This method works fine on newer devices. The dropdown item layouts are fine on all devices. But Froyo does this weird text overlapping when I use a custom dropdown item layout. Each selection just gets piled on top of the last one.

This question: Spinner does not wrap text -- is this an Android bug? about text wrapping in Spinners suggests that only way to do it is recreating the styling from scratch without inheriting, but that sounds crazy and prone to problems.

my_simple_list_item_1.xml:

<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android" 
  android:layout_width="300dp"
  android:layout_height="wrap_content" >   

  <TextView
    android:id="@+id/android:text1"
    android:layout_width="wrap_content"
    android:layout_height="50dp"
    android:ellipsize="marquee"
    android:layout_gravity="center_vertical"
    android:singleLine="false"/>
</LinearLayout> 

Java:

    import org.holoeverywhere.widget.Spinner;

    spinner1.setAdapter(ArrayAdapter.createFromResource(this,
            R.array.array_of_strings, R.layout.my_simple_list_item_1));

Answer

Michael Alan Huff picture Michael Alan Huff · Apr 13, 2013

I found a solution. The text was wrapping as the spinners initial display could only handle textviews, and I had found another solution recommending the use of a linear layout. This made the dropdown of the spinner look correct. As it turns out adapters have a resource called setDropDownViewResource() which allows you to set a different view for the dropdown than what is displayed in the spinner's selection.

 import org.holoeverywhere.widget.Spinner;

 ArrayAdapter adapter1 = ArrayAdapter.createFromResource(this,R.array.array_of_strings,R.layout.simple_list_item_1);
 adapter1.setDropDownViewResource(R.layout.my_simple_list_item_1);
 spQ1.setAdapter(adapter1);

in this example the simple_list_item is the default view supplied by android and mY_simple_list_item is

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="300dp"
android:layout_height="wrap_content" >   

<TextView
  android:id="@+id/android:text1"
  android:layout_width="wrap_content"
  android:layout_height="50dp"
  android:ellipsize="marquee"
  android:layout_gravity="center_vertical"
  android:singleLine="false"/>

</LinearLayout> 

Now the text wraps inside the dropdown view of the spinner AND in the spinners displayed selection.