Подтвердить что ты не робот

Список ListView List в Android, не отображающий фон элемента по умолчанию

Прочитали ряд связанных вопросов здесь, в 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>

Список, на который вы ссылаетесь, здесь (в основном заимствован из списка состояний 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 и попытаюсь добавить конкретный андроид: фон, который указывает на @drawable/shape_row, каждая строка получает правильный фон, НО при нажатии, в фокусе, и т.д. не могут обрабатываться (или, по крайней мере, не могут быть замечены, поскольку фон никогда не изменяется).

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

Спасибо,

Пол

EDIT:

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

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

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

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

normal, unselected list with background set

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

selected, with drawSelectorOnTop set to true

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

selected, no background

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

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

4b9b3361

Ответ 1

Выяснилось, что проблема заключалась в том, что, когда я правильно настраивал 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

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

Если вы хотите, чтобы все ваши View использовали список состояний, тогда вы должны указать, где определены дочерние элементы 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, созданный/используемый, и что он расположен в том же ограничительном прямоугольнике, что и выбранный элемент.

Ответ 3

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