android listview полупрозрачный выбор цвета строки

Мне нужно реализовать полупрозрачный выбор строки в списке, а также для «нажатого» состояния.

Если я применяю сплошной цвет, то все работает как положено. Но если я применяю полупрозрачный цвет (# 44444444), то я вижу цвет выбора по умолчанию (оранжевый на моем андроиде 2.3), а поверх него мой цвет (он немного тускнеет оранжевым).

Почему у меня оранжевый цвет? Как решить эту проблему?

Вот мой код: Селектор xml в drawable/listselectorinvisible.xml

<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="false"
    android:state_selected="false"
    android:drawable="@color/transparent" />

<item android:state_pressed="true" 
    android:drawable="@color/semitransparent" />

<item android:state_selected="true" android:state_pressed="false"
    android:drawable="@color/semitransparent" />
</selector>

Строка списка определена в layout/topscore_row.xml

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" 
android:layout_height="wrap_content" 
android:layout_width="fill_parent"
android:background="@drawable/listselectorinvisible">
  <TextView android:layout_height="wrap_content" android:id="@+id/scrowNum" android:textColor="@color/fontButColor" android:text="#" android:textSize="24sp" android:layout_width="32dip" android:gravity="right|top" android:layout_gravity="top"></TextView>
  <LinearLayout android:layout_height="wrap_content" android:id="@+id/scrowNamLay" android:layout_width="142dip" android:orientation="vertical">
    <TextView android:layout_height="wrap_content" android:paddingTop="2dip" android:layout_width="fill_parent" android:id="@+id/scrowPlayer" android:textColor="@color/fontButColor" android:text="@string/tblPlayer" android:textSize="24sp" android:paddingLeft="2dip"></TextView>
    <TextView android:layout_height="wrap_content" android:layout_width="fill_parent" android:id="@+id/scrowOpPlayer" android:textColor="@color/fontButColor" android:text="@string/tblPlayer" android:textSize="14sp" android:paddingLeft="2dip"></TextView>
  </LinearLayout>
  <ImageView android:id="@+id/scrowImg" android:layout_height="wrap_content" android:src="@drawable/small_im_bt" android:padding="2dip" android:layout_marginTop="2dip" android:layout_width="26dip"></ImageView>
  <TextView android:layout_height="wrap_content" android:layout_width="48dip" android:id="@+id/scrowScore" android:layout_marginRight="5dip" android:gravity="right" android:textColor="@color/fontButColor" android:text="@string/tblScore" android:textSize="26sp"></TextView>
  <TextView android:layout_height="wrap_content" android:id="@+id/scrowTime" android:textColor="@color/fontButColor" android:text="@string/tblTime" android:gravity="center_horizontal" android:textSize="26sp" android:layout_width="58dip"></TextView>
</LinearLayout>

И, наконец, сам список:

<ListView android:layout_width="match_parent" android:id="@+id/scoreList" android:paddingLeft="5dip" android:paddingRight="5dip" 
  android:cacheColorHint="#00000000" 
  android:choiceMode="none" 
  android:clickable="false" 
  android:focusable="false" 
  android:focusableInTouchMode="false" 
  android:longClickable="false" android:layout_height="298dip">
</ListView>

После неудачной установки цвета в xml я также попытался установить listselectorinvisible в моем CustomArrayAdapter с помощью convertView.setBackgroundResource(R.drawable.listselectorinvisible);, но безуспешно.

Код CustomAdapter:

        /* (non-Javadoc)
     * @see android.widget.ArrayAdapter#getView(int, android.view.View, android.view.ViewGroup)
     */
    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        View v = convertView;
        if (v == null) 
        {
            LayoutInflater vi = (LayoutInflater)app.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = vi.inflate(R.layout.topscore_row, null);
        }

        Score score = objects.get(position);
        int color = getColor(position, score);

        if (score != null) 
        {
            ImageView iv = (ImageView) v.findViewById(R.id.scrowImg);
            if (iv != null) 
            {
                iv.setImageResource(imgs[score.gameType]);
            }
            TextView tv = (TextView) v.findViewById(R.id.scrowNum);
            tv.setText(Integer.toString(position+1) + ".");
            tv.setTypeface(app.mainFont);
            tv.setTextColor(color);
            .... ....               
        }

        v.setBackgroundResource(R.drawable.listselectorinvisible);

        return v;

    }               

Заранее спасибо.


person Northern Captain    schedule 01.06.2011    source источник


Ответы (3)


Вы должны установить android:listSelector="@drawable/listcolor" в ListView

Ваш ListView будет

<ListView android:layout_width="match_parent" android:id="@+id/scoreList" android:paddingLeft="5dip" android:paddingRight="5dip" 
  android:cacheColorHint="#00000000" 
  android:choiceMode="none" 
  android:clickable="false" 
  android:focusable="false" 
  android:focusableInTouchMode="false" 
  android:longClickable="false" 
android:listSelector="@drawable/listcolor"
android:layout_height="298dip">
</ListView>

Посмотрите на приведенный ниже URL

Как установить цвет выделения в ListView

Спасибо, Дипак.

person Sunil Kumar Sahoo    schedule 01.06.2011
comment
Интересно, спасибо. Однако мне интересно, не замедляет ли это работу, поскольку подавляет механизм оптимизации cacheColorHint. Я попробую сегодня вечером с полупрозрачным цветом, как предложил Северный капитан, мне нравится этот дизайн. - person Snicolas; 01.06.2011
comment
Спасибо за предложение. Я только что попробовал это на эмуляторе, и оранжевый цвет исчез, я вижу только свой полупрозрачный. Но этот цвет также применяется ко всему списку, пока я нажимаю элемент в списке. На реальном устройстве не пробовал, нет с собой, может это глюк эмулятора... - person Northern Captain; 01.06.2011
comment
@Snicolas - я также пробовал ваш код с addStatesFromChildren, но это ничего не меняет - person Northern Captain; 01.06.2011
comment
Проверил атрибут android:listSelector на реальном устройстве и получил тот же эффект: в нажатом состоянии цвет селектора применяется ко всему списку, а не только к нажатой строке. Есть идеи? - person Northern Captain; 01.06.2011

После нескольких часов игры с той же проблемой я наконец нашел решение.

Во-первых, в ListView установите listSelector="@android:color/transparent" (здесь @null почему-то не работает)

Во-вторых, сделайте так, чтобы самый родительский фон вашей строки был отрисовываемым с отслеживанием состояния (возможно, с отслеживанием состояния цвета) с state_pressed="@color/with_transparency"

person Max Ch    schedule 02.03.2014
comment
Я бы добавил к этому, что безопасно установить цвет фона списка на что-то твердое, что большинство людей хотели бы сделать, я думаю - person Daniel Wilson; 02.03.2015

Я не знаю, имеет ли это значение, но у вашего селектора нет состояния по умолчанию (оно должно быть последним).

Кроме того, это не отвечает на ваш вопрос, но в строке top_score рассмотрите возможность добавления следующего в ваш xml в корневой макет:

android:addStatesFromChildren="true" 

Он скажет, что элемент списка улавливает состояние дочерних элементов, то есть составной компонент действует как один компонент и принимает состояние любого компонента внутри. (например, если выбран один, то становится выбран составной компонент).

С уважением, Стефан

person Snicolas    schedule 01.06.2011