Effetto a catena su Android Lollipop CardView


192

Sto cercando di ottenere un CardView per visualizzare l'effetto a catena quando viene toccato impostando l'attributo android: backgound nel file XML dell'attività come descritto qui nella pagina degli sviluppatori Android, ma non funziona. Nessuna animazione, ma viene chiamato il metodo in onClick. Ho anche provato a creare un file ripple.xml come suggerito qui , ma lo stesso risultato.

CardView come appare nel file XML dell'attività:

<android.support.v7.widget.CardView
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_width="155dp"
    android:layout_height="230dp"
    android:elevation="4dp"
    android:translationZ="5dp"
    android:clickable="true"
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:onClick="showNotices"
    android:background="?android:attr/selectableItemBackground"
    android:id="@+id/notices_card"
    card_view:cardCornerRadius="2dp">

</android.support.v7.widget.CardView> 

Sono relativamente nuovo allo sviluppo di Android, quindi avrei potuto fare alcuni ovvi errori.

Risposte:


594

È necessario aggiungere quanto segue a CardView:

android:foreground="?android:attr/selectableItemBackground"
android:clickable="true"

8
Funziona su lecca-lecca con effetto a catena ma dona tinta unita solo quando viene eseguito su piattaforme più vecchie. Abbastanza buono per me :)
mach

16
Una piccola osservazione: ho notato che l'attributo cliccabile non è necessario e può anche rompere alcune cose! Avevo un GridView pieno di CardView visualizzabili e l'ascoltatore non funzionava correttamente. Ho rimosso il tag cliccabile dall'XML e ora tutto funziona alla perfezione
Joaquin Iurchuk,

2
@joaquin senza il clic, fa sì che l'ondulazione abbia origine solo dal centro
frostymarvelous

2
?android:attr/selectableItemBackgroundrichiede il livello API 11
Pratik Butani,

9
Lavorare senza android:clickable="true".
Sean,

30

Aggiungi questi due righe di codice nella tua vista xml per dare un effetto a catena su cardView.

android:clickable="true"
android:foreground="?android:attr/selectableItemBackground"

Eccezionale! foregroundfunziona con viste di sfondo personalizzate come un fascino! Bello!
sud007,

24

Sono riuscito a ottenere l'effetto a catena sul cardview di:

<android.support.v7.widget.CardView 
    xmlns:card_view="http://schemas.android.com/apk/res-auto" 
    android:clickable="true" 
    android:foreground="@drawable/custom_bg"/>

e per il custom_bg che puoi vedere nel codice sopra, devi definire un file xml per entrambi i dispositivi lollipop (nel pacchetto drawable-v21) e pre-lollipop (nel pacchetto drawable). per custom_bg nel pacchetto drawable-v21 il codice è:

<ripple 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="?android:attr/colorControlHighlight">
<item
    android:id="@android:id/mask"
    android:drawable="@android:color/white"/>
</ripple>

per custom_bg nel pacchetto drawable, il codice è:

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

<item android:state_pressed="true">
    <shape>
        <solid android:color="@color/colorHighlight"></solid>
    </shape>
</item>
<item>
    <shape>
        <solid android:color="@color/navigation_drawer_background"></solid>
    </shape>
</item>
</selector>

quindi sui dispositivi pre-lecca-lecca avrai un solido effetto click e sui dispositivi lecca-lecca avrai un effetto a catena sul cardview.


1
Ciao, mi rendo conto applicando selettore (o ondulazione) sul primo piano di CardView, bloccherà i bambini in CardView stesso - stackoverflow.com/questions/33763403/... Posso sapere fare si rileva lo stesso prob come ho fatto io? O mi manca qualcosa? Grazie.
Cheok Yan Cheng,

@CheokYanCheng: Non sto affrontando alcun problema come il tuo, ma direi per esperienza personale che cardView ha alcuni bug per il pre-lecca-lecca. Evita di usare cardview: proprietà quota in pre-lecca-lecca. Quanto sopra funziona bene per me e altri voti.
Rahul Ahuja,

Posso sapere qual è il valore di colorHighlight & navigation_drawer_background. Se hai usato il tuo colore definito senza trasparenza, puoi ancora vedere i figli della tua carta?
Cheok Yan Cheng il

@CheokYanCheng: i valori sono as, <color name = "navigation_drawer_background"> ​​# FFFFFF </color> <color name = "colorHighlight"> # FF8A65 </color>
Rahul Ahuja

Non lavoro per il mio caso. Uso il tuo selettore come primo piano. Come previsto, il colore bianco solido (navigation_drawer_background), che viene utilizzato come primo piano della visualizzazione delle carte, bloccherà la visibilità di tutti i bambini - i.imgur.com/CleYh5B.png Ecco come appare senza applicare il selettore come primo piano - i.imgur. com / ZXk5Aoq.png
Cheok Yan Cheng,

14

L'effetto a catena è stato omesso nella libreria di supporto di appcompat che è ciò che stai usando. Se vuoi vedere l'ondulazione usa la versione Android L e testala su un dispositivo Android L. Per il sito AppCompat v7:

"Perché non ci sono increspature su Pre-Lollipop? Molto di ciò che consente a RippleDrawable di funzionare senza problemi è il nuovo RenderThread di Android 5.0. Per ottimizzare le prestazioni delle versioni precedenti di Android, per ora abbiamo lasciato RippleDrawable fuori."

Dai un'occhiata a questo link qui per maggiori informazioni


Quello sarebbe. Grazie!
AkraticCritic

39
Ma come metteresti l'effetto a catena su cardView per Android Lollipop allora?
sviluppatore Android

Quindi devo decidere tra compatibilità all'indietro usando appcompat o avere tutti i nuovi effetti, usando le classi dal core Android ma limitandomi all'API 21?
Urs Reupke,

Potresti creare 2 APK uno per 21+ e l'altro per <21. O dividere il codice poiché 21+ non utilizzerà supportActionbar ecc. Potrebbe sembrare un sacco di problemi, ma credo sia il tuo solletico.
Mathijs Segers,

1
Ecco perché al momento non è possibile scrivere applicazioni Android L "pure". A partire da luglio 2015 sceglierai come target il 12% della base utenti Android.
Glenn Bech,

10

Se l'app su minSdkVersioncui stai lavorando è di livello 9, puoi utilizzare:

android:foreground="?selectableItemBackground"
android:clickable="true"

Invece, a partire dal livello 11, usi:

android:foreground="?android:attr/selectableItemBackground"
android:clickable="true"

Dalla documentazione:

cliccabile : definisce se questa vista reagisce agli eventi clic. Deve essere un valore booleano, "vero" o "falso".

primo piano : definisce il disegno da disegnare sul contenuto. Questo può essere usato come overlay. Il disegno in primo piano partecipa all'imbottitura del contenuto se la gravità è impostata per riempire.


Usando android: foreground = "? Android: attr / selectableItemBackground" ha funzionato per la compatibilità AndroidX, grazie!
dianakarenms,

6

Per me, l'aggiunta di foregrounda CardViewnon ha funzionato (motivo sconosciuto: /)

L'aggiunta dello stesso al layout figlio ha fatto il trucco.

CODICE:

<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:id="@+id/card_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:focusable="true"
    android:clickable="true"
    card_view:cardCornerRadius="@dimen/card_corner_radius"
    card_view:cardUseCompatPadding="true">

    <LinearLayout
        android:id="@+id/card_item"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:foreground="?android:attr/selectableItemBackground"
        android:padding="@dimen/card_padding">

    </LinearLayout>
</android.support.v7.widget.CardView>

2
Questo perché il bambino intercetta l'evento, se provi qualcosa come aggiungere il riempimento alla scheda (qualcosa come 20dp) e fai clic sulla parte in cui il riempimento sarebbe, allora vedrai l'effetto a catena anche senza che il bambino abbia l'attributo in primo piano impostato
Cruces

1
Questo ha funzionato anche per me, utilizzando i nuovi componenti materiali: com.google.android.material.card.MaterialCardView. Avevo un elevatore stateListAnimator per la vista della scheda per regolare l'elevazione e l'ondulazione applicata al layout del vincolo interno con lo sfondo dell'elemento selezionabile in primo piano senza attributo selezionabile.
Patty P

Non me lo ricordo ora, ma c'è un modo per impostare le visualizzazioni secondarie in modo che non reagiscano all'evento click
Someone Somewhere

3

Aggiungi questi due come il lavoro del codice come un incantesimo per qualsiasi vista come Button, Linear Layout o CardView Basta mettere queste due linee e vedere la magia ...

android:foreground="?android:attr/selectableItemBackground"
android:clickable="true"

2

Se esiste un layout radice come RelativeLayout o LinearLayout che contiene tutto il componente dell'elemento adattatore in CardView, è necessario impostare l'attributo di sfondo in quel layout radice. piace:

<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="122dp"
android:layout_marginBottom="6dp"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
card_view:cardCornerRadius="4dp">

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/touch_bg"/>
</android.support.v7.widget.CardView>

2

Evento Ripple per il Cardviewcontrollo Android :

<android.support.v7.widget.CardView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:foreground="?android:attr/selectableItemBackground"
    android:clickable="true"
    android:layout_marginBottom="4dp"
    android:layout_marginTop="4dp" />

1

Non ero contento di AppCompat, quindi ho scritto il mio CardView e le increspature backportate. Qui funziona su Galaxy S con Gingerbread, quindi è sicuramente possibile.

Demo di Ripple su Galaxy S

Per maggiori dettagli controlla il codice sorgente .


il collegamento è interrotto
temirbek

1

Aggiungi quanto segue al tuo XML:

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

E aggiungi al tuo adattatore (se è il tuo caso)

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            val attrs = intArrayOf(R.attr.selectableItemBackground)
            val typedArray = holder.itemView.context.obtainStyledAttributes(attrs)
            val selectableItemBackground = typedArray.getResourceId(0, 0)
            typedArray.recycle()

            holder.itemView.isClickable = true
            holder.itemView.isFocusable = true
            holder.itemView.foreground = holder.itemView.context.getDrawable(selectableItemBackground)
        }
    }

0

Per coloro che cercano una soluzione al problema dell'effetto a catena che non funziona su un CardView creato programmaticamente (o nel mio caso vista personalizzata che estende CardView) che viene mostrato in un RecyclerView, il seguente ha funzionato per me. Sostanzialmente dichiarare gli attributi XML citati nelle altre risposte in modo dichiarativo nel file di layout XML non sembra funzionare per un CardView creato a livello di programmazione o uno creato da un layout personalizzato (anche se la vista di root è CardView o viene utilizzato l'elemento di unione), quindi devono essere impostati programmaticamente in questo modo:

private class MadeUpCardViewHolder extends RecyclerView.ViewHolder {
    private MadeUpCardView cardView;

    public MadeUpCardViewHolder(View v){
        super(v);

        this.cardView = (MadeUpCardView)v;

        // Declaring in XML Layout doesn't seem to work in RecyclerViews
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            int[] attrs = new int[]{R.attr.selectableItemBackground};
            TypedArray typedArray = context.obtainStyledAttributes(attrs);
            int selectableItemBackground = typedArray.getResourceId(0, 0);
            typedArray.recycle();

            this.cardView.setForeground(context.getDrawable(selectableItemBackground));
            this.cardView.setClickable(true);
        }
    }
}

Dove MadeupCardView extends CardViewKudos a questa risposta per la TypedArrayparte.


0
  android:foreground="?android:attr/selectableItemBackgroundBorderless"
   android:clickable="true"
   android:focusable="true"

Lavorando solo con api 21 e utilizzalo per non utilizzare questa vista a righe della lista


0

Usa invece Material Cardview, estende Cardview e offre molteplici nuove funzionalità incluso l'effetto cliccabile predefinito:

<com.google.android.material.card.MaterialCardView>

...

</com.google.android.material.card.MaterialCardView>

Dipendenza

implementation 'com.google.android.material:material:1.0.0'
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.