Добавление эффекта ряби в элемент RecyclerView

Я пытаюсь добавить Ripple Effect к элементу 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, к которому я пытаюсь добавить эффект:

3 ответа

Я понял. Единственное, что мне нужно было сделать, это добавить этот атрибут:

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>

Результат:

Как уже было сказано, самое простое решение - просто добавить одно из следующих RecyclerView фон строки:

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

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

Пользовательский эффект ряби

Этот ответ начинается с этого простого примера Android RecyclerView. Это будет выглядеть следующим образом.

Пример эффекта ряби GIF

Добавить селектор для устройств до API 21

До API 21 (Android 5.0 Lollipop), нажав RecyclerView элемент просто изменил цвет фона (без эффекта ряби). Это то, что мы собираемся сделать тоже. Если у вас все еще есть пользователи с этими устройствами, они привыкли к такому поведению, поэтому мы не будем сильно о них беспокоиться. (Конечно, если вы действительно хотите, чтобы для них тоже был эффект пульсации, вы можете использовать собственную библиотеку.)

Щелкните правой кнопкой мыши на вашем res/drawable папку и выберите New > 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 Effect для устройств API 21+

Щелкните правой кнопкой мыши на вашем res/drawable папку и выберите New > 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:background="?android:attr/selectableItemBackground" попробуйте добавить следующие строки в корень макета.

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

Это позволит убедиться, что вид кликабелен и активирует эффект ряби с атрибутом background, упомянутым выше.

Добавьте эти строки в корневое представление xml вашего адаптера

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

Использование стиля кнопки

Это работало для меня бесчисленное количество раз.

Добавьте стиль кнопки без полей к корневому элементу макета. Нет необходимости вfocusable или clickable Атрибуты, стиль по умолчанию инкапсулирует все это за вас.

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

Простой и индивидуальный подход - установить тему представления, как описано здесь.

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>

Другие пользовательские реализации можно найти здесь.

Другие вопросы по тегам