views:

46

answers:

1

I have created a ListView with TextViews as items - most of which have a certain color as background, but some have a custom @drawable/shape as background (i.e. the top and bottom items, which have rounded corners). These backgrounds are set as part of state-lists, to provide another background color when the items are tapped. The listSelector of the ListView is set to transparent, and instead the contained TextViews in the items are set to clickable.

ListView:

<ListView android:id="@+id/allreminders_list" android:layout_width="fill_parent" 
android:layout_height="fill_parent"
android:dividerHeight="3px" android:cacheColorHint="#00000000"
android:divider="@color/trans" android:background="@drawable/reminderlist_background"
android:listSelector="@android:color/transparent"/>

ListView entry:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="?android:attr/listPreferredItemHeight"
android:id="@+id/entry_container">
<TextView android:id="@+id/remindername" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:text="dummy"
android:padding="15dp" android:layout_marginLeft="15px"
android:layout_marginRight="15px" style="@style/ReminderEntry"
android:clickable="true"/>
</RelativeLayout>

Programmatical setting of ListView entry background:

if (position == 1)
textViewReminderName
  .setBackgroundResource(R.drawable.reminder_entry_state_top);
else if (position == remindersInSection)
textViewReminderName
  .setBackgroundResource(R.drawable.reminder_entry_state_bottom);
else
textViewReminderName
  .setBackgroundResource(R.drawable.reminder_entry_state);

State-list for top items (R.drawable.reminder_entry_state_top):

<selector xmlns:android="http://schemas.android.com/apk/res/android"&gt;
<item android:state_pressed="true" android:drawable="@drawable/rounded_top_corners_selected" />
<item android:state_selected="true" android:drawable="@drawable/rounded_top_corners_selected" />
<item android:drawable="@drawable/rounded_top_corners" />

Shape for unselected top items (@drawable/rounded_top_corners):

<shape xmlns:android="http://schemas.android.com/apk/res/android"&gt; 
<solid android:color="@color/entry_background"/>    
<corners android:bottomRightRadius="0dp" android:bottomLeftRadius="0dp" 
 android:topLeftRadius="5dp" android:topRightRadius="5dp"/> 
</shape>

This stuff works, functionally. BUT, the top and bottom items (which have the shape-drawable as background, which is shown above) change their color slightly under certain conditions:

  • After scrolling down the list without tap-stopping the scroll
  • After clicking any item in the list

The correct color of those items is only shown when I scroll the list without removing the finger before scrolling has ended.

What can this possibly be? A bug in the way StateListDrawables present drawable shapes?

A: 

After endless research and guesswork, I've found the reason myself: Dithering! By disabling dithering in the state-list selectors, the problem magically disappeared:

<selector xmlns:android="http://schemas.android.com/apk/res/android" android:dither="false">

It seems that dithering is only applied under certain conditions (as described above) which is IMHO not expected behaviour, yet treatable by disabling it completely.

manmal