【问题标题】:I just can't seem to highlight a row in an Android ListView我似乎无法突出显示 Android ListView 中的一行
【发布时间】:2016-05-25 17:02:54
【问题描述】:

当用户按下并释放它(释放后,突出显示仍然存在)时,我试图突出显示(更改背景颜色)ListView 中的一行。我已经阅读了数十篇帖子,两天来,我尝试了所有方法,但无法使其正常工作。我读过帖子说这取决于您使用的是鼠标还是触摸屏。有人说做不到。我的问题是:这可以在这个操作系统和触摸屏上完成吗?如果是这样,如何(或我做错了什么)?

我在旧手机(2.2.3 操作系统版本)上运行。我读到了this bug。我也在扩展 ArrayAdapter,所以每一行都可以有一个图像(图标)和文本。

以下 sn-p 来自 ListView 的 Activity xml。请注意choiceMode和listSelector:

    <ListView
    android:layout_width="match_parent"
    android:layout_height="178dp"
    android:id="@+id/listView"
    android:layout_gravity="center_horizontal"
    android:layout_weight="0.95"
    android:choiceMode="singleChoice"
    android:longClickable="false"
    android:clickable="false"
    android:listSelector="@drawable/list_view_selector"/>

由于这个旧操作系统中的错误,我为各种颜色的矩形形状创建了几个可绘制的 xml 文件,用于测试和调试我的尝试。这是 list_selector_green.xml 的一个:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
   android:shape="rectangle">

    <solid android:color="#00ff00" />

</shape>

我的 list_view_selector.xml 文件是:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
    android:state_selected="false"
    android:state_pressed="false"
    android:drawable="@drawable/list_selector_red" />
<item
    android:state_selected="false"
    android:state_pressed="true"
    android:drawable="@drawable/list_selector_purple" />
<item
    android:state_selected="true"
    android:state_pressed="false"
    android:drawable="@drawable/list_selector_green" />
<item
    android:state_selected="true"
    android:state_pressed="true"
    android:drawable="@drawable/list_selector_orange" />
</selector>

我为点击事件创建了一个监听器。我在这里尝试了各种东西(它们被注释掉了)。

        myListView.setOnItemClickListener(new AdapterView.OnItemClickListener()
    {

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long arg3)
        {
            view.setSelected(true);
            //myListView.setSelection(position);
            //parent.requestFocusFromTouch(); // nothing gets selected
            //parent.setSelected(true); // something (ListView?) gets selected
            ///parent.setBackgroundColor(Color.GREEN); // makes whole listview background green
            //view.setBackgroundColor(Color.GREEN); // does nothing
            //parent.setSelection(position); // does nothing
        }
    });

所以,当我按下一个项目时,背景确实会改变颜色,但当我松开时,它会恢复到我认为是透明的“正常”。我认为它的行为就像没有被选中一样。到目前为止,我最接近的是调用 parent.setSelected(true),我认为它选择了整个 ListView。当我这样做时,第一次按下是紫色的,第二次按下是橙色的,所以系统似乎确实检测到某些东西被选中。它只是没有持续下去。

还有一件可能相关的事情。请注意,在我的 list_view_selector.xml 文件中,如果 state_selected 和 state_pressed 为 false,则颜色为红色。因此,我期望初始背景是红色的,但事实并非如此——它是默认的(透明的?)。

【问题讨论】:

  • android:listSelector="@drawable/list_view_selector" 我认为应该是 android:background
  • 嘿,丹。我试过了,虽然它确实在启动时将背景更改为红色,但在发布后背景又恢复为红色。
  • 你试过我的方法了吗?

标签: android listview


【解决方案1】:

忘记 setSelected 并让我提供我的方式:

创建一个int数组,在onClick方法中检查数组是否包含位置,如果不添加。

现在您要做的就是检查适配器中的 getView 方法是否该位置在数组中,如果是 - 更改背景。

这里有一些代码:

 if(!selected_messages.contains(position))
        {
            selected_messages.add(position);             

            getViewByPosition(position, conversation_list).findViewById(R.id.messageParent).setBackgroundColor(ContextCompat.getColor(context, R.color.background_selected_message));

        }


        /// CONTAINS

        else
        {
            selected_messages.remove(selected_messages.indexOf(position));


            getViewByPosition(position, conversation_list).findViewById(R.id.messageParent).setBackgroundColor(ContextCompat.getColor(context, android.R.color.transparent));
        }

getViewByPosition 方法:

   public static View getViewByPosition(int pos, ListView listView)
{
    final int firstListItemPosition = listView.getFirstVisiblePosition();
    final int lastListItemPosition = firstListItemPosition + listView.getChildCount() - 1;

    if (pos < firstListItemPosition || pos > lastListItemPosition )
    {
        return listView.getAdapter().getView(pos, null, listView);
    }


    else
    {
        final int childIndex = pos - firstListItemPosition;
        return listView.getChildAt(childIndex);
    }
}

在适配器中:

  if(selected_messages.contains(position))
            {
                convertView.findViewById(R.id.background).setBackgroundColor(ContextCompat.getColor(chat, R.color.background_selected_message));
            }

            else
            {
convertView.findViewById(R.id.background).setBackgroundColor(ContextCompat.getColor(chat, android.R.color.transparent));
            }

最后,这是我用于数组的类,因为常规类没有“包含”方法。

 public static class Countable_arrayList_int extends ArrayList<Integer>
{

    @Override
    public boolean contains(Object o)
    {
        return indexOf(o) >= 0;
    }


}

【讨论】:

  • 所以,显然我的方法不适用于操作系统版本。我了解您的解决方案:您跟踪所选项目并在自定义适配器中,当它被要求显示视图时查找它,然后更改背景颜色。它工作正常。谢谢。
  • 是的,很高兴为您提供帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-14
  • 1970-01-01
  • 2012-01-22
相关资源
最近更新 更多