Hinzufügen eines Ripple-Effekts zum RecyclerView-Element

103

Ich versuche, dem Element von RecyclerView einen Ripple-Effekt hinzuzufügen. Ich habe online nachgesehen, konnte aber nicht finden, was ich brauche. Ich gehe davon aus, dass es sich um einen benutzerdefinierten Effekt handeln muss. Ich habe das android: background-Attribut für RecyclerView selbst ausprobiert und auf "? Android: selectableItemBackground" gesetzt, aber es hat nicht funktioniert.:

    <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"/>

Dies ist die RecyclerView, zu der ich den Effekt hinzufügen möchte:

Geben Sie hier die Bildbeschreibung ein

Georgi Koemdzhiev
quelle
1
Ich öffne dies als kein Duplikat dieser Frage . Obwohl die Lösungen ähnlich sein können, gibt es bestimmte Aspekte einer CardViewFrage, die sich nicht auf diese allgemeinere Frage beziehen.
Suragch
@ Suragch Danke, dass Sie den Unterschied bemerkt haben :)
Georgi Koemdzhiev

Antworten:

218

Ich fand heraus. Das einzige, was ich tun musste, war dieses Attribut hinzuzufügen:

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

zum Stammelement des Layouts, das mein RecyclerView-Adapter so aufbläst:

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

Ergebnis:

Geben Sie hier die Bildbeschreibung ein

Wenn Sie den Welligkeitseffekt immer noch nicht sehen können, fügen Sie diese Linien auch dem Stammelement des Layouts hinzu.

android:clickable="true"
android:focusable="true"
Georgi Koemdzhiev
quelle
3
Was ist, wenn das Stammelement CardView ist?
Nabin
6
@SpiderMan Sie sollten Ihren Code in ein relatives oder ein lineares Layout schreiben und ihn dann in das Kartenlayout einfügen.
SanVed
7
@pronoobsanved, das hat mir geholfen! Für diejenigen, die immer noch mit dem Problem konfrontiert sind, verwendet CardView als Kind ein einzelnes Layout. Stellen Sie für dieses Kind klickbar, fokussierbar als wahr und Hintergrund als? Attr / selectedableItemBackground
Vamsi Challa
42
@NabinKhadka für eine CardView setzen es stattdessen als Vordergrund, dhandroid:foreground="?android:attr/selectableItemBackground"
Lorne Laliberte
6
Ich musste die Option android:clickable="true"auch hinzufügen , um diese Arbeit zu machen
Joaquin Iurchuk
68

Wie bereits beantwortet, besteht die einfachste Lösung darin, eine der folgenden RecyclerViewOptionen als Hintergrund für Ihre Zeile hinzuzufügen :

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

Wenn Sie jedoch Probleme mit dieser Methode haben oder eine genauere Kontrolle über die Farben wünschen, können Sie Folgendes tun.

Benutzerdefinierter Welleneffekt

Diese Antwort beginnt mit diesem einfachen Android RecyclerView-Beispiel . Es sieht wie im folgenden Bild aus.

Beispiel für einen Welleneffekt GIF

Selektor für Geräte vor API 21 hinzufügen

Vor API 21 (Android 5.0 Lollipop) hat das Klicken auf ein RecyclerViewElement nur seine Hintergrundfarbe geändert (kein Welleneffekt). Das werden wir auch tun. Wenn Sie noch Benutzer mit diesen Geräten haben, sind diese an dieses Verhalten gewöhnt, sodass wir uns nicht zu viele Sorgen um sie machen müssen. (Wenn Sie den Ripple-Effekt auch für sie wirklich nutzen möchten, können Sie natürlich eine benutzerdefinierte Bibliothek verwenden .)

Klicken Sie mit der rechten Maustaste auf Ihren res/drawableOrdner und wählen Sie Neu> Zeichnungsressourcendatei . Nennen Sie es custom_ripple. Klicken Sie auf OK und fügen Sie den folgenden Code ein.

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>

Ich habe colorAccentals Hervorhebungsfarbe für den Druckzustand verwendet, da dieser bereits verfügbar war, aber Sie können jede gewünschte Farbe definieren.

Ripple-Effekt für API 21+ -Geräte hinzufügen

Klicken Sie mit der rechten Maustaste auf Ihren res/drawableOrdner und wählen Sie Neu> Zeichnungsressourcendatei . Rufen Sie es noch custom_rippleeinmal an. Klicken Sie diesmal jedoch nicht auf OK. Von der Available - Qualifikationsliste Version und dann auf die >> Taste und schreibt 21für die API - Ebene Plattform . Klicken Sie nun auf OK und fügen Sie den folgenden Code ein.

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>

Wieder habe ich colorAccentfür die Welligkeitsfarbe verwendet, weil sie verfügbar war, aber Sie können jede gewünschte Farbe verwenden. Die Maske beschränkt den Welligkeitseffekt nur auf das Zeilenlayout. Die Maskenfarbe spielt anscheinend keine Rolle, deshalb habe ich nur ein undurchsichtiges Weiß verwendet.

Als Hintergrund festlegen

Stellen Sie im Stammlayout Ihres RecyclerView-Elements den Hintergrund auf die von uns erstellte benutzerdefinierte Welligkeit ein.

android:background="@drawable/custom_ripple"

In dem Beispielprojekt , mit dem wir begonnen haben, sieht es folgendermaßen aus:

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

Fertig

Das ist es. Sie sollten jetzt in der Lage sein, Ihr Projekt auszuführen. Dank dieser Antwort und diesem YouTube-Video für Hilfe.

Suragch
quelle
Wenn Sie eine Standardhintergrundfarbe haben möchten, entfernen Sie einfach die Zeile 'android: id = "@ android: id / mask' und stellen Sie die Farbe des Zeichens auf die gewünschte Farbe ein.
Jordan Hochstetler
26

Ich denke, es gibt ein kleines Detail, das übersehen wird.

Wenn Sie nach dem Hinzufügen immer noch keinen Welligkeitseffekt erhalten android:background="?android:attr/selectableItemBackground", fügen Sie die folgenden Zeilen im Stammverzeichnis des Layouts hinzu.

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

Dadurch wird sichergestellt, dass die Ansicht anklickbar ist, und der Welligkeitseffekt mit dem oben genannten Hintergrundattribut wird aktiviert

Sriram R.
quelle
5

Fügen Sie diese Zeilen in die Adapter-XML-Stammansicht ein

android:background="?attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
Gundu Bandgar
quelle
2

Ein einfacher und benutzerdefinierter Ansatz besteht darin, ein Ansichtsthema wie hier beschrieben festzulegen .

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>

Weitere benutzerdefinierte Implementierungen finden Sie hier .

Adam Hurwitz
quelle
1

Verwenden eines Schaltflächenstils

Das hat bei mir unzählige Male funktioniert.

Fügen Sie den randlosen Schaltflächenstil zum Stammelement Ihres Layouts hinzu. Es gibt keine Notwendigkeit für focusableoder clickableAttribute, die Standard - Styling alles , was für Sie kapselt.

<androidx.constraintlayout.widget.ConstraintLayout
    style="@android:style/Widget.Material.Button.Borderless"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
Felix Favor Chinemerem
quelle
cool, aber diese zusätzliche Polsterung
ededede
@ededede Sie können die XML-Attribute min-height, max-height, width ... verwenden, um sie nach Ihrem Geschmack zu optimieren.
Felix Favor Chinemerem