Android selectableItemВыбор выбора

Я хочу изменить фон моего представления, когда состояние "активировано", и я хочу сохранить эффекты (пульсации) ?attr:selectableItemBackground. Можно ли расширить или объединить селектор ?attr:selectableItemBackground?

Ответ 1

Вы можете использовать LayerDrawable, чтобы нарисовать эффект эффекта пульсации (?attr:selectableItemBackground) над цветом активированного состояния.

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <selector>
            <item android:state_activated="true">
                <color android:color="?attr/colorPrimary"/>
            </item>
            <item>
                <color android:color="@android:color/transparent"/>
            </item>
        </selector>
    </item>
    <item android:drawable="?attr/selectableItemBackground"/>
</layer-list>

Edit: Поскольку невозможно использовать атрибуты темы в XML-чертеже перед API 21, кажется, что лучше использовать эффект ряби, который можно вырезать в качестве вырезаемого переднего плана, а активированный селектор цветов можно использовать в качестве фона для рисования.

<View
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/yourView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:foreground="?attr/selectableItemBackground"
    android:background="@drawable/activated_color_selector">

С res/drawable/activated_color_selector.xml, содержащим:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_activated="true">
        <!-- Can't use the ?attr/colorPrimary before API 21 -->
        <color android:color="@color/primaryColor"/>
    </item>
    <item>
        <color android:color="@android:color/transparent"/>
    </item>
</selector>

Ответ 2

Чтобы изменить цвет пульсации во всем приложении, вы можете разместить это в своей теме приложения

<item name="colorControlHighlight">@color/ripple</item>

Ответ 3

К сожалению, единственный способ, который я нашел, - это иметь дополнительный вид в вашем макете, который будет эмулировать выбранное состояние. Вот так (работает и на pre-Lollipop):

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="?attr/listPreferredItemHeight"
    android:background="?attr/selectableItemBackground">

    <View
        android:id="@+id/item_selected"
        android:visibility="gone"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="?attr/colorControlHighlight"/>

    <android.support.v7.widget.AppCompatTextView
        android:id="@+id/item_title"
        android:layout_gravity="center_vertical"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:layout_marginBottom="8dp"
        android:layout_marginLeft="16dp"
        android:layout_marginRight="16dp"
        android:textAppearance="?attr/textAppearanceListItem"/>

</FrameLayout>

Затем в вашем адаптере вы устанавливаете видимость item_selected либо в View.VISIBLE либо в View.GONE, исходя из необходимости сделать этот конкретный элемент выбранным.

PS Очевидно, что в этом решении используется библиотека поддержки AppCompat, поэтому для ее использования в файл build.gradle необходимо добавить build.gradle строку:

implementation 'com.android.support:appcompat-v7:28.0.0'