Список состояния Android ListView не показывает фон элемента по умолчанию - PullRequest
13 голосов
/ 19 января 2011

Прочитал несколько связанных с этим вопросов здесь, в SO, а также просмотрел документы и исходники по Android, чтобы попытаться это выяснить, но я озадачен, хотя, учитывая, что listSelector, кажется, применяет стили только к выбранным элементам Я не в шоке ...

У меня есть Listview, определенный в main.xml здесь:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <ListView  
    android:id="@android:id/list"
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"
    android:fadingEdgeLength="5dp"
    android:divider="#000000"
        android:dividerHeight="1dp"
        android:listSelector="@drawable/list_selector" />
    <TextView 
    android:id="@android:id/empty"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:gravity="center"
        android:singleLine="false"
        android:text="@string/message_list_empty" />
</FrameLayout>

Ссылка на listSelector находится здесь (заимствована в основном из списка состояний Android по умолчанию, найденного в SDK: /android/platforms/android-8/data/res/drawable/list_selector_background.xml):

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- the window has lost focus, disable the items -->
    <item 
        android:state_window_focused="false"
        android:drawable="@drawable/shape_row_disabled" />

    <!-- the list items are disabled -->
    <item 
        android:state_enabled="false"
        android:state_focused="true" 
        android:state_pressed="true"
        android:drawable="@drawable/shape_row_disabled" />
    <item 
        android:state_enabled="false"
        android:state_focused="true" 
        android:drawable="@drawable/shape_row_disabled" />
    <item 
        android:state_enabled="false"
        android:drawable="@drawable/shape_row_disabled" />

    <!-- the list items are enabled and being pressed -->
    <item 
        android:state_focused="true" 
        android:state_pressed="true"
        android:drawable="@drawable/shape_row_transition" />
    <item 
        android:state_focused="false" 
        android:state_pressed="true"
        android:drawable="@drawable/shape_row_transition" />

    <!-- the list items are enabled and being used -->
    <item
        android:state_focused="true"
        android:drawable="@drawable/shape_row_selected" />

    <!-- the default item -->
    <item 
        android:drawable="@drawable/shape_row" />
</selector>

Нарисованы ссылки на формы, прямоугольники со скругленными углами, например:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
android:shape="rectangle">
    <gradient 
        android:startColor="#EF6100"
        android:centerColor="#FF8E00" 
        android:endColor="#EF6100" 
        android:angle="270" /> 
    <corners 
        android:bottomRightRadius="7dp" 
        android:bottomLeftRadius="7dp"
        android:topLeftRadius="7dp" 
        android:topRightRadius="7dp" /> 
</shape>

Таким образом, конечным результатом должен быть ListView с элементами с фоном @ drawable / shape_row по умолчанию, а затем разноцветными фонами в зависимости от состояния. Когда я запускаю свой список, все работает нормально с точки зрения того, когда состояния активны, например, когда элемент получает фокус, нажат и т. Д., Но сами элементы имеют прозрачный фон, когда ни один не выбран (т.е. состояние просмотра по умолчанию). Я надеялся, что последнее правило Государственного списка,

<item android:drawable="@drawable/shape_row" />

захватит это состояние, но по какой-то причине оно не работает. Я переместил вещи вокруг и попробовал различные настройки, и ничего. Если я отредактирую файл row.xml, который я использую для определения элементов списка в ListView, и попытаюсь добавить определенный android: background, который указывает на @ drawable / shape_row, каждая строка получает правильный фон, НО при нажатии, в фокусе, состояния etc не обрабатываются (или, по крайней мере, не видны, поскольку фон никогда не изменяется).

Кто-нибудь может указать мне правильное направление здесь? Я так близок к тому, чтобы уложить это в постель, но, попробовав почти все, просто не могу заставить элементы ListView брать фон по умолчанию И отвечать на реализованный список состояний через android: listSelector.

Спасибо

Пол

EDIT:

Также только что попытался добавить android: itemBackground = "@ drawable / shape_row" в ListView в main.xml, и неудивительно, что не повезло (в документе указано, что его следует использовать для задания фона элементов меню, но он думал, что это стоит снимок с элементами списка).

Еще одна попытка, добавив android: visible = "true" к каждому определению селектора и элемента. Документы StateListDrawable, кажется, указывают, что "Предоставляет начальное состояние видимости рисованного объекта; значение по умолчанию - false" , но добавление этого ничего не изменило.

EDIT2: Таким образом, на основании исследования, проведенного Qberticus ниже, кажется, что в каждом представлении может быть только один набор селекторов списка, что подтверждает поведение селектора списка. Я также могу подтвердить, что установка android: drawSelectorOnTop действительно перемещает селектор IN FRONT выбранного элемента, но это, конечно, затемняет сам элемент, так что я вижу только сам селектор (который в моем случае имеет цветную форму).

Вот как выглядит список с заданными фонами:

normal, unselected list with background set

Из-за установленного фона внешний вид не изменяется при выборе элементов. Если я изменю директиву android: drawSelectorOnTop на true и выберу элемент, я получу:

selected, with drawSelectorOnTop set to true

И, наконец, если я не установил фоновое изображение для элементов списка, селектор работает должным образом, но, конечно же, фоновых изображений нет, так как последнее правило StateSelector не выполняется (не так ли выступать в роли ловушки?) для невыбранных предметов, означающих отсутствие хороших округлых фигур:

selected, no background

Итак, моя проблема остается; если я не устанавливаю фон для каждого элемента списка, я вижу, что селектор работает, но элементы не имеют фона, когда они не выбраны. Если я устанавливаю фон для элемента, они отлично смотрятся, когда не выделены, но фон скрывает селектор. Разве просто невозможно иметь элемент списка уникальной формы с рабочими селекторами?

Спасибо всем, кто может весить.

Ответы [ 3 ]

9 голосов
/ 31 января 2011

Понял это, проблема заключалась в том, что когда я правильно устанавливал listSelector для ListView в список состояний через android:listSelector="@drawable/list_selector", мне также нужно было установить фон для элемента списка в другой список состояний через android:background="@drawable/list_background"

В списке состояний list_background.xml у меня есть:

<?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>

Нашел ответ здесь:

Изменение цвета фона элементов ListView на Android

В сочетании с моим списком выбора выше, он работает отлично.

2 голосов
/ 19 января 2011

listSelector используется только для указания View, который будет отображаться в том же месте, что и выбранный элемент View. То есть, есть только один экземпляр listSelector за ListView. Вы можете указать, может ли он рисовать сверху или нет, используя drawSelectorOnTop.

Если вы хотите, чтобы все ваши View s использовали список состояний, вам следует указать, где определены дочерние элементы View.

Я использую источник для AbsListView в качестве ссылки. В частности, AbsListView#setSelector(Drawable), AbsListView#positionSelector, AbsListView#drawSelector и 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();
    }
}

Источник указывает, что существует только один mSelector созданный / использованный и что он расположен в том же ограничительном прямоугольнике, что и элемент selected .

0 голосов
/ 23 января 2013

Вы можете назначить фон по умолчанию для корневого макета и selector_background для дочернего, в этом случае, если элемент не выбран, фон по умолчанию не скрывает селектор. Его работа для меня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...