Додавання ефекту Ripple до елемента RecyclerView


105

Я намагаюся додати ефект Ripple до елемента RecyclerView. Я подивився в Інтернеті, але не зміг знайти те, що мені потрібно. Я припускаю, що це має бути на замовлення. Я спробував атрибут android: background для самого RecyclerView і встановив його на "? Android: selectableItemBackground", але він не працював:

    <android.support.v7.widget.RecyclerView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:focusable="true"
    android:clickable="true"
    android:background="?android:selectableItemBackground"
    android:id="@+id/recyclerView"
    android:layout_below="@+id/tool_bar"/>

Це RecyclerView, який я намагаюся додати ефекту до:

введіть тут опис зображення


1
Я знову відкриваю це як не дублікат цього питання . Хоча рішення можуть бути схожими, є певні аспекти виникнення CardViewпитання в цьому питанні, ніж вони не стосуються цього більш загального питання.
Сурагч

@Suragch Дякую за те, що помітили різницю :)
Георгій Кемджієв

Відповіді:


222

Я зрозумів. Єдине, що мені довелося зробити - це додати цей атрибут:

android:background="?android:attr/selectableItemBackground"

до кореневого елемента макета, який мій адаптер RecyclerView надуває так:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingTop="8dp"
    android:paddingBottom="8dp"
    android:background="?android:attr/selectableItemBackground"
    tools:background="@drawable/bg_gradient">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="17sp"
        android:layout_marginLeft="15dp"
        android:layout_marginStart="15dp"
        android:id="@+id/shoppingListItem"
        android:hint="@string/enter_item_hint"
        android:layout_centerVertical="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"/>

    <CheckBox
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/shopping_list_item_checkbox_label"
        android:id="@+id/shoppingListCheckBox"
        android:layout_centerVertical="true"
        android:layout_marginRight="15dp"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"
        android:checked="false"/>

</RelativeLayout>

Результат:

введіть тут опис зображення

Якщо ви все ще не можете побачити ефект пульсації, додайте ці рядки також до кореневого елемента макета.

android:clickable="true"
android:focusable="true"

3
Що робити, якщо кореневим елементом є CardView?
Набін

6
@SpiderMan Ви повинні написати свій код у відносному чи лінійному макеті, а потім розмістити його всередині макета картки.
SanVed

7
@pronoobsanved, це мені допомогло! Для тих, хто все ще стикається з проблемою, CardView приймає єдиний макет як дитина. Для цієї дитини встановіть справжній і фоновий зображення, що можна натискати, фокусуватися як? Attr / selectedableItemBackground
Vamsi Challa

42
@NabinKhadka для CardView замість цього встановив її як передній план, тобтоandroid:foreground="?android:attr/selectableItemBackground"
Lorne Laliberte

6
Мені довелося додати можливість android:clickable="true"також зробити цю роботу
Хоакін Юрчук

69

Як уже було сказано, найпростішим рішенням є просто додати одне з наведених нижче як RecyclerViewтло вашого рядка:

  • android:background="?android:attr/selectableItemBackground"
  • android:background="?attr/selectableItemBackground"

Однак якщо у вас виникли проблеми з цим методом або ви хочете більш тонкий контроль над кольорами, то можете зробити наступне.

Спеціальний ефект Ripple

Ця відповідь починається з цього простого прикладу Android RecyclerView . Це буде виглядати як наступне зображення.

Приклад ефекту Ripple GIF

Додайте селектор для попередніх пристроїв API 21

Перед API 21 (Android 5.0 Lollipop) натискання RecyclerViewелемента просто змінило колір тла (ефекту пульсації). Це ми також будемо робити. Якщо у вас все ще є користувачі з цими пристроями, вони звикли до такої поведінки, тому ми не будемо надто їх хвилювати. (Звичайно, якщо ви теж хочете ефекту пульсацій для них, ви можете скористатися спеціальною бібліотекою .)

Клацніть правою кнопкою миші вашу res/drawableпапку і виберіть Створити> Drawable файл ресурсів . Зателефонуйте custom_ripple. Клацніть OK і вставте наступний код.

custom_ripple.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true">
        <shape android:shape="rectangle">
            <solid android:color="@color/colorAccent" />
        </shape>
    </item>
    <item>
        <shape android:shape="rectangle">
            <solid android:color="@android:color/transparent" />
        </shape>
    </item>
</selector>

Я використовував colorAccentяк колір виділення для натиснутого стану, оскільки він уже був доступний, але ви можете визначити, який колір ви хочете.

Додати ефект Ripple для пристроїв API 21+

Клацніть правою кнопкою миші вашу res/drawableпапку і виберіть Створити> Drawable файл ресурсів . Зателефонуйте custom_rippleще раз. Не натискайте ОК, однак цього разу. У списку Доступні класифікатори виберіть Версія , потім натисніть кнопку >> та напишіть 21для рівня API платформи . Тепер натисніть кнопку OK і вставте наступний код.

v21 / custom_ripple.xml

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@color/colorAccent">

    <item
        android:id="@android:id/mask"
        android:drawable="@android:color/white" />
</ripple>

Знову ж таки, я використовував colorAccentдля пульсації колір, тому що він був доступний, але ви можете використовувати будь-який колір, який ви хочете. Маска обмежує ефект пульсації лише компонуванням рядків. Колір маски, мабуть, не має значення, тому я просто використовував непрозорий білий.

Встановити як тло

У кореневому макеті вашого елемента RecyclerView встановіть фон для створеної нами власної пульсації.

android:background="@drawable/custom_ripple"

У прикладі проекту, з якого ми розпочали, це виглядає приблизно так:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:background="@drawable/custom_ripple"
    android:padding="10dp">

    <TextView
        android:id="@+id/tvAnimalName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="20sp"/>

</LinearLayout>

Готово

Це воно. Ви повинні мати можливість запустити свій проект зараз. Завдяки цій відповіді та цьому відео YouTube на допомогу.


Якщо ви хочете мати фоновий колір за замовчуванням, просто видаліть рядок 'android: id = "@ android: id / mask', а потім встановіть колір малювання у будь-що, що вам завгодно
Jordan Hochstetler

26

Я думаю, що є одна маленька деталь, яка пропущена.

Якщо ви все ще не отримаєте ефект пульсації після додавання, android:background="?android:attr/selectableItemBackground"спробуйте додати ці наступні рядки в корінь макета.

android:clickable="true"
android:focusable="true"

Це дозволить переконатися, що представлення можна натискати, і дасть змогу ефект пульсації з атрибутом фону, згаданим вище


5

додайте ці рядки у кореневий вигляд адаптера xml

android:background="?attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"

2

Простий і нестандартний підхід - це встановити тему перегляду, як описано тут .

some_view.xml

<ImageView
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:background="?attr/selectableItemBackgroundBorderless"
   android:focusable="true"
   android:src="@drawable/up_arrow"
   android:theme="@style/SomeButtonTheme"/>

some_style.xml

<style name="SomeButtonTheme" >
   <item name="colorControlHighlight">@color/someColor</item>
</style>

Тут можна знайти інші користувацькі реалізації .


1

Використання стилю кнопки

Це працювало для мене незліченна кількість.

Додайте стиль кнопки без полів до кореневого елемента вашого макета. Немає потреби focusableчи clickableатрибутів, стиль за замовчуванням інкапсулює все, що для вас.

<androidx.constraintlayout.widget.ConstraintLayout
    style="@android:style/Widget.Material.Button.Borderless"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

круто, але це додавання прокладки
ededede

@ededede Ви можете використовувати атрибути мінімальної висоти, максимальної висоти, ширини ... Атрибути XML для налаштування на ваш смак.
Фелікс Фавор Кінерем
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.