Come creare un'increspatura circolare su un pulsante quando viene cliccato?


121

sfondo

Nell'app dialer di Android, quando inizi a cercare qualcosa e fai clic sul pulsante freccia a sinistra di EditText, ottieni un effetto a catena circolare su di esso:

inserisci qui la descrizione dell'immagine

Il problema

Ho provato ad averlo anche io, ma ne ho preso uno rettangolare:

    <ImageButton
        android:id="@+id/navButton"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="8dp"
        android:background="?android:attr/selectableItemBackground"
        android:src="@drawable/search_ic_back_arrow"/>

La domanda

Come faccio a fare in modo che il pulsante abbia un effetto a catena circolare quando viene cliccato? Devo creare un nuovo disegnabile, o c'è un modo integrato per quello?




1
Considera la possibilità di cambiare la risposta selezionata a quella con il maggior numero di voti positivi, in quanto risolve effettivamente il problema
Jeff Barger,

@ JeffBarger Perché? Entrambi funzionano bene. Non c'è nessuno migliore tra loro.
sviluppatore Android

Risposte:


18

Se hai già un'immagine di sfondo, ecco un esempio di un'increspatura simile a selectableItemBackgroundBorderless:

            <ImageButton
                android:id="@+id/btn_show_filter_dialog"
                android:layout_width="24dp"
                android:layout_height="24dp"
                android:background="@drawable/ic_filter_state"/>

ic_filter_state.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:state_pressed="true"
        android:state_enabled="true"
        android:drawable="@drawable/state_pressed_ripple"/>
    <item
        android:state_enabled="true"
        android:drawable="@drawable/ic_filter" />
</selector>

state_pressed_ripple.xml: (opacità impostata al 10% su sfondo bianco) 1AFFFFFF

 <?xml version="1.0" encoding="UTF-8"?>    
    <ripple xmlns:android="http://schemas.android.com/apk/res/android">
        <item>
            <shape android:shape="oval">
                <solid android:color="#1AFFFFFF"/>
            </shape>
            <color android:color="#FFF"/>
        </item>
    </ripple>

288

Se stai usando il tema AppCompat, puoi impostare lo sfondo della vista come:

android:background="?selectableItemBackgroundBorderless"

Ciò aggiungerà un'increspatura circolare su 21 e superiori e uno sfondo quadrato su 21 inferiori.


Bello. Posso anche impostarne il colore in qualche modo?
sviluppatore Android

4
nell'API 23 lo sfondo "su" sembra essere la metà delle dimensioni rispetto a selectbleItemBackgroundBorderless
snodnipper

3
Bella, migliore risposta. ty
Skywalker

1
@androiddeveloper, il colore può essere impostato impostando colorControlHighlight come di seguito in styles.xml <item name = "colorControlHighlight"> # F00 </item>
bond

4
Se lo si utilizza all'interno di altri layout, potrebbe essere necessario anche android:clipChildren="false"nei layout per consentire la propagazione dell'animazione.
Tanasis

83

Un altro attributo con effetto ondulazione rotondo, specialmente per la barra delle azioni:

android:background="?actionBarItemBackground"

UPD : il colore dell'ondulazione può essere modificato da questo attributo:

<!--somewhere in styles-->
<item name="colorControlHighlight">your_color_here</item>

Ma tieni presente che questo attributo si applica a tutti gli effetti a catena predefiniti.


Qualche modo per personalizzarlo? Ad esempio il colore? Forse qualcosa negli stili? O ancora più specificamente nel tag XML della vista stesso?
sviluppatore Android

Non lo so, oggi ho risolto questo problema e le risposte sopra non hanno funzionato come mi serviva. Presumo che il colore possa essere personalizzato negli stili, ma sicuramente non nella vista.
Anrimian

1
Questo è esattamente l'effetto giusto che sto cercando. A proposito, puoi menzionare dove trovare questo attributo, sembra non essere documentato.
Jack Wang

2
Risponde alla domanda dell'OP. Dovrebbe essere contrassegnato come migliore risposta. +1
Corbella

2
@MeysamHadigheh ?è una scorciatoia per?attr/
musooff

47

Crea e imposta un'increspatura disegnabile come sfondo. Qualcosa come questo.

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@color/grey_15">
    <item android:id="@android:id/mask">
        <shape android:shape="oval">
            <solid android:color="?android:colorPrimary"/>
        </shape>
        <color android:color="@color/white"/>
    </item>
</ripple>

È qualcosa nel mio codice. Puoi usare i tuoi colori :)
Thomas R.

Come dovrei utilizzare il selettore predefinito nel caso in cui sia pre-Lollipop? Inoltre, usa gli stessi colori di quello sul dialer?
sviluppatore Android

2
Puoi mettere ripple drawable nella tua cartella drawables-v21. E per pre L utilizzare uno stato disegnabile semplice. Usa lo stesso nome di file e mettilo nella cartella disegnabile (predefinita).
Thomas R.

2
Puoi anche creare uno stile. Nella cartella values-v21 creare un nuovo stile e impostare l'increspatura disegnabile come sfondo. E per pre L, cioè nella cartella dei valori styles.xml, metti come sfondo l'attributo "selectableItemBackground" per lo stesso stile.
Thomas R.

1
Se desideri lo stesso colore di increspatura degli altri effetti a catena predefiniti utilizzati nell'app, utilizza "? Attr / colorControlHighlight" come colore.
alexbchr

27

Basta aggiungere questo sfondo alla tua visualizzazione

android:background=?android:attr/actionBarItemBackground


19

Puoi creare un'increspatura del cerchio disegnabile usando l' android:radiusattributo in xml.

Esempio:

<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="your_color"
    android:radius="your_radius" />

Fai attenzione, che your_radiusdovresti essere inferiore alla larghezza e all'altezza della tua vista. Ad esempio: se hai vista con dimensione 60dp x 60dp your_radiusdovrebbe essere vicino 30dp(larghezza / 2 o altezza / 2).

Funziona su Android 5.0 e versioni successive.


3

Se vuoi file XML più generici, ho due file:

1) btn_ripple_background con codice:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
    android:state_pressed="true"
    android:state_enabled="true"
    android:drawable="@drawable/ripple_circular_shape"/>
</selector>

2) ripple_circuler_shape con codice:

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

infine l'utilizzo:android:foreground="@drawable/ripple_btn_background"


2

Se vuoi un effetto a catena che non attraversi il confine del cerchio, puoi controllare questo codice. Per me funziona perfettamente. Ricorda solo che devi dare id = @ android: id / mask in ripple_blue.xml

<ImageButton
    android:id="@+id/send_password_to_mail_image_view"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/ripple_blue"
    android:src="@drawable/ic_filter" />

ripple_blue.xml

<ripple
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@color/colorRipple">

    <item android:id="@android:id/mask">

        <shape android:shape="oval">
            <solid android:color="@color/colorWindowBackground"/>
        </shape>

    </item>

    <item android:id="@android:id/background">

        <shape android:shape="oval">
            <solid android:color="@color/colorWindowBackground"/>
        </shape>

    </item>

</ripple>

color.xml

<resources xmlns:tools="http://schemas.android.com/tools">
    <color name="colorWindowBackground">#F2F5FC</color>
    <color name="colorRipple">#0288d1</color>
</resources>

1

Provare:

android:background="@android:color/transparent"
android:clickable="true"
android:focusable="true"
android:foreground="?actionBarItemBackground"

1
Per favore, non pubblicare solo codice come risposta, ma includi una spiegazione su cosa fa il tuo codice e come risolve il problema della domanda. Le risposte con una spiegazione sono generalmente di qualità superiore e hanno maggiori probabilità di attirare voti positivi.
Mark Rotteveel

Più agevole rispetto all'impostazione di actionBarItemBackground come sfondo. Ma ancora non esattamente come l'animazione della barra delle azioni stessa.
coolcool1994


0

In Kotlin / Java puoi fare quanto segue

fun View.applyCircularRippleEffect() {
    val backgroundResId = context.getResource(android.R.attr.actionBarItemBackground)

    if (backgroundResId != 0) {
        setBackgroundResource(backgroundResId)
        isClickable = true
        isFocusable = true
    }
}

// getResource extension
fun Context.getResource(resourceId: Int): Int {
    val out = TypedValue()
    theme.resolveAttribute(resourceId, out, true)

    return out.resourceId
}

context.getResource non trovato
Rahul Mandaliya

@RahulMandaliya grazie per il commento. Colpa mia, era il mio metodo di estensione personalizzato. Aggiunto alla risposta
mihails.kuzmins
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.