Android ListView状态列表未显示默认项目背景

已经在SO上阅读了一些相关的问题,并通过Android文档和源代码查看了这一点,但是我很难过,尽管listSelector似乎只对所选项目应用样式,但是我没有震惊……

我在main.xml中定义了Listview:

     

引用的listSelector在这里(主要借用SDK中的默认Android状态列表:/android/platforms/android-8/data/res/drawable/list_selector_background.xml):

                 

引用的drawables是形状,圆角矩形,如下所示:

      

因此,最终结果应该是ListView,默认情况下具有@ drawable / shape_row背景的项目,然后根据状态设置不同的彩色背景。 当我启动列表时,一切都可以正常运行状态,例如项目获得焦点,按下等等,但是当没有选择项目时,项目本身具有透明背景(即默认视图状态)。 我曾希望国家清单的最后一条规则,

  

将捕获该状态,但由于某种原因它不起作用。 我已经移动了一些东西,尝试了不同的设置,什么都没有。 如果我编辑用于在ListView中定义列表项的row.xml文件并尝试添加指向@ drawable / shape_row的特定android:background,则每行都会获得正确的背景,但是在按下时,在焦点上,等状态未能处理(或至少,不能被视为背景永远不会改变)。

任何人都能指出我在正确的方向吗? 我很接近把这个放到床上,但在尝试了几乎所有东西之后,只是无法获取ListView项目采用默认背景并通过android:listSelector响应实现的State List。

谢谢,

保罗

编辑:

还尝试将android:itemBackground =“@ drawable / shape_row”添加到main.xml中的ListView,毫不奇怪的是没有运气(文档声明它应该用于指定菜单项的背景,但认为值得用列表拍摄项目)。

尝试了另一件事,为每个选择器和项目定义添加了android:visible =“true”。 StateListDrawable文档似乎表明“提供drawable的初始可见性状态;默认值为false” ,但添加此更改没有。

EDIT2:所以,基于Qberticus下面的研究,似乎每个视图只能有一组列表选择器,这确认了列表选择器的行为。 我还可以确认设置android:drawSelectorOnTop确实会移动所选项目的选择器IN FRONT,但这当然会遮挡项目本身,这样我只能看到选择器本身(在我的情况下是彩色形状)。

以下是背景设置列表的样子:

正常的,未选择的列表与背景设置

由于设置了背景,选择项目时外观没有变化。 如果我将android:drawSelectorOnTop指令更改为true并选择一个项目,我得到:

选中,将drawSelectorOnTop设置为true

最后,如果我没有为列表项设置背景图像,选择器按预期工作,但当然,没有背景图像,因为StateSelector的最后一条规则似乎没有被遵循(不应该作为一个catchall?)对于未选择的项目,意味着没有漂亮的自定义圆形形状:

选中,没有背景

所以,我的问题仍然存在; 如果我没有为每个列表项设置背景,我可以看到选择器工作但是未选中时项目没有背景。 如果我为项目设置背景,则在未选中时它们看起来很棒,但背景会遮挡选择器。 难道不可能拥有一个具有工作选择器的独特形状的列表项吗?

感谢能够减肥的任何人。

想通了这个问题,问题是当我通过android:listSelector="@drawable/list_selector"正确地将ListView的listSelector设置为State List时,我还需要将列表项的背景设置为另一个状态列表android:background="@drawable/list_background"

在list_background.xml状态列表中,我有:

 < ?xml version="1.0" encoding="utf-8"?>         

在这里find答案:

在Android上更改ListView项目的背景颜色

结合我上面的列表选择器,它完美地工作。

listSelector仅用于指定将在与所选项 View相同的位置绘制的View 。 即,每个ListView只有一个listSelector实例。 您可以使用drawSelectorOnTop指定它是否可以在顶部绘制。

如果希望所有View都使用状态列表,则应指定定义子View的位置。

我正在使用AbsListView的源AbsListView作为参考。 特别是AbsListView#setSelector(Drawable)AbsListView#positionSelectorAbsListView#drawSelectorAbsListView#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(); } } 

源指示只创建/使用了一个mSelector ,并且它与所选项目位于相同的边界矩形中。

您可以为子布局指定默认背景,为子节点指定selector_background,在这种情况下,如果未选择项目,则默认背景不会遮挡选择器。 它的工作对我来说。