Android ListView State List not showing default item background
Figured this out, the issue was that while I was setting the listSelector for the ListView to the State List correctly via android:listSelector="@drawable/list_selector"
, I also needed to set the background for the list item to another State List via android:background="@drawable/list_background"
In the list_background.xml state list, I have:
<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android"android:visible="true"> <!-- the list items are disabled --><item android:state_window_focused="false" android:drawable="@drawable/shape_row_disabled" /> <!-- the list items are enabled, in focus but not being touched/pressed (idle) --> <item android:state_window_focused="true" android:state_pressed="false" android:state_focused="false" android:state_selected="false" android:drawable="@drawable/shape_row" /> <!-- the catch-all --> <item android:drawable="@android:color/transparent" /></selector>
Found the answer here:
Changing background color of ListView items on Android
In conjunction with my list selector above, it works perfectly.
The listSelector
is only used to specify a View
that will be drawn in the same place as the selected item View
. I.e., there is only one instance of the listSelector
per ListView
. You can specify if it can draw on top or not using drawSelectorOnTop
.
If you want all your View
s to use a state list then you should specify that where the child View
s are defined.
I'm using the source for AbsListView
as reference. Specifically AbsListView#setSelector(Drawable)
, AbsListView#positionSelector
, AbsListView#drawSelector
, and AbsListView#dispatchDraw
AbsListView#drawSelector
:
private void drawSelector(Canvas canvas) { if (shouldShowSelector() && mSelectorRect != null && !mSelectorRect.isEmpty()) { final Drawable selector = mSelector; selector.setBounds(mSelectorRect); selector.draw(canvas); }}
AbsListView#positionSelector
:
void positionSelector(View sel) { final Rect selectorRect = mSelectorRect; selectorRect.set(sel.getLeft(), sel.getTop(), sel.getRight(), sel.getBottom()); positionSelector(selectorRect.left, selectorRect.top, selectorRect.right, selectorRect.bottom); final boolean isChildViewEnabled = mIsChildViewEnabled; if (sel.isEnabled() != isChildViewEnabled) { mIsChildViewEnabled = !isChildViewEnabled; refreshDrawableState(); }}
The source indicates that there is only one mSelector
created/used and that it is positioned in the same bounding rect as the selected item.
You can assign default background for root layout and selector_background for child, in this case if item not selected then default background not obscures the selector. Its work for me.