Aggiunta dell'effetto a catena all'elemento RecyclerView


105

Sto provando ad aggiungere l'effetto Ripple all'elemento di RecyclerView. Ho dato un'occhiata online, ma non sono riuscito a trovare quello che mi serve. Presumo che debba essere un effetto personalizzato. Ho provato l'attributo android: background allo stesso RecyclerView e l'ho impostato su "? Android: selectableItemBackground" ma non ha funzionato .:

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

Questo è il RecyclerView a cui sto cercando di aggiungere l'effetto:

inserisci qui la descrizione dell'immagine


1
Lo riapro perché non è un duplicato di questa domanda . Sebbene le soluzioni possano essere simili, ci sono alcuni aspetti dell'avere una CardViewin quella domanda che non riguardano questa domanda più generale.
Suragch

@ Suragch Grazie per aver notato la differenza :)
Georgi Koemdzhiev

Risposte:


222

Ho capito. L'unica cosa che ho dovuto fare è aggiungere questo attributo:

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

all'elemento radice del layout che il mio adattatore RecyclerView si gonfia in questo modo:

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

Risultato:

inserisci qui la descrizione dell'immagine

Se ancora non riesci a vedere l'effetto a catena, aggiungi queste linee anche all'elemento radice del layout.

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

3
E se l'elemento radice è CardView?
Nabin

6
@SpiderMan Dovresti scrivere il tuo codice all'interno di un layout relativo o lineare e poi posizionarlo all'interno del layout della scheda.
SanVed

7
@pronoobsanved, questo mi ha aiutato! Per coloro che stanno ancora affrontando il problema, CardView utilizza un unico layout da bambino. Per quel bambino, imposta cliccabile, attivabile come true e sfondo come?
Attr

42
@NabinKhadka per un CardView lo ha impostato come primo piano invece, ovveroandroid:foreground="?android:attr/selectableItemBackground"
Lorne Laliberte

6
Ho dovuto aggiungere anche l'opzione android:clickable="true"per farlo funzionare
Joaquin Iurchuk

69

Come già risposto, la soluzione più semplice è semplicemente aggiungere uno dei seguenti come RecyclerViewsfondo della riga:

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

Tuttavia, se si verificano problemi con questo metodo o se si desidera un controllo più preciso sui colori, è possibile eseguire le seguenti operazioni.

Effetto ondulazione personalizzato

Questa risposta inizia con questo semplice esempio di Android RecyclerView . Assomiglierà alla seguente immagine.

GIF di esempio effetto ondulazione

Aggiungi selettore per dispositivi pre API 21

Prima dell'API 21 (Android 5.0 Lollipop), facendo clic su un RecyclerViewelemento ne cambiava il colore di sfondo (nessun effetto a catena). Questo è anche quello che faremo. Se hai ancora utenti con quei dispositivi, sono abituati a quel comportamento, quindi non ci preoccuperemo troppo di loro. (Ovviamente, se vuoi davvero l'effetto a catena anche per loro, potresti usare una libreria personalizzata .)

Fare clic con il pulsante destro del mouse sulla res/drawablecartella e scegliere Nuovo> File di risorse disegnabili . Chiamalo custom_ripple. Fare clic su OK e incollare il codice seguente.

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>

Ho usato colorAccentcome colore di evidenziazione per lo stato premuto perché era già disponibile, ma puoi definire il colore che desideri.

Aggiungi effetto a catena per dispositivi API 21+

Fare clic con il pulsante destro del mouse sulla res/drawablecartella e scegliere Nuovo> File di risorse disegnabili . Chiamalo di custom_ripplenuovo. Tuttavia, questa volta non fare clic su OK. Dall'elenco Qualificatori disponibili scegli Versione , quindi fai clic sul pulsante >> e scrivi 21per il livello API della piattaforma . Ora fai clic su OK e incolla il codice seguente.

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>

Ancora una volta, ho usato colorAccentper il colore ondulato perché era disponibile, ma puoi usare qualsiasi colore tu voglia. La maschera limita l'effetto a catena solo al layout delle righe. Il colore della maschera apparentemente non ha importanza, quindi ho usato solo un bianco opaco.

Imposta come sfondo

Nel layout radice del tuo elemento RecyclerView, imposta lo sfondo sul ripple personalizzato che abbiamo creato.

android:background="@drawable/custom_ripple"

Nel progetto di esempio con cui abbiamo iniziato, assomiglia a questo:

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

Finito

Questo è tutto. Dovresti essere in grado di eseguire il tuo progetto ora. Grazie a questa risposta e questo video di YouTube per aiuto.


Se vuoi avere un colore di sfondo predefinito, rimuovi la riga "android: id =" @ android: id / mask "e quindi imposta il colore del disegnabile come preferisci.
Jordan Hochstetler

26

Penso che ci sia un piccolo dettaglio che manca.

Se ancora non si ottiene l'effetto a catena dopo l'aggiunta, android:background="?android:attr/selectableItemBackground"provare ad aggiungere le seguenti righe nella radice del layout.

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

Questi assicureranno che la vista sia selezionabile e abiliterà l'effetto a catena con l' attributo di sfondo menzionato sopra


5

aggiungi queste righe nella vista root xml dell'adattatore

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

2

Un approccio semplice e personalizzato consiste nell'impostare un tema di visualizzazione come descritto qui .

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>

Altre implementazioni personalizzate possono essere trovate qui .


1

Utilizzo di uno stile pulsante

Questo ha funzionato per me innumerevoli.

Aggiungi lo stile del pulsante senza bordi all'elemento principale del layout. Non sono necessari focusableclickableattributi, lo stile predefinito racchiude tutto ciò per te.

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

bello, ma questo aggiunge imbottitura
ededede

@ededede Puoi usare gli attributi XML min-height, max-height, width ... per modificarlo secondo i tuoi gusti.
Felix Favor Chinemerem
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.