Comment créer une ondulation circulaire sur un bouton lorsque vous cliquez dessus?


122

Contexte

Sur l'application de numérotation d'Android, lorsque vous commencez à rechercher quelque chose et que vous cliquez sur le bouton fléché à gauche de EditText, vous obtenez un effet d'entraînement circulaire dessus:

entrez la description de l'image ici

Le problème

J'ai essayé de l'avoir aussi, mais j'en ai un rectangulaire:

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

Comment faire en sorte que le bouton ait un effet d'entraînement circulaire lorsqu'on clique dessus? Dois-je créer un nouveau dessinable, ou y a-t-il un moyen intégré pour cela?




1
Envisagez de changer la réponse sélectionnée par celle avec le plus de votes positifs, car cela résout le problème
Jeff Barger

@JeffBarger Pourquoi? Les deux fonctionnent bien. Il n'y en a pas de meilleur entre eux.
développeur android le

Réponses:


18

Si vous avez déjà une image d'arrière-plan, voici un exemple d'ondulation qui ressemble à 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é définie à 10% sur fond blanc) 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>

290

Si vous utilisez le thème AppCompat, vous pouvez définir l'arrière-plan de la vue comme suit:

android:background="?selectableItemBackgroundBorderless"

Cela ajoutera une ondulation circulaire sur 21 et au-dessus et un fond carré sur en dessous de 21.


Agréable. Puis-je également définir la couleur de celui-ci d'une manière ou d'une autre?
développeur android

4
dans l'API 23, l'arrière-plan `` haut '' semble être la moitié de la taille par rapport à selectbleItemBackgroundBorderless
snodnipper

3
Belle, meilleure réponse. ty
Skywalker

1
@androiddeveloper, la couleur peut être définie en définissant colorControlHighlight comme ci-dessous dans votre styles.xml <item name = "colorControlHighlight"> # F00 </item>
bond

4
Si vous l'utilisez dans d'autres mises en page, vous devrez peut-être android:clipChildren="false"également permettre à l'animation de se propager.
Tanasis

83

Un autre attribut avec effet d'entraînement rond, spécialement pour la barre d'action:

android:background="?actionBarItemBackground"

UPD : la couleur d'ondulation peut être modifiée par cet attribut:

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

Mais gardez à l'esprit que cet attribut s'applique à tous les effets d'entraînement par défaut.


Un moyen de le personnaliser? Par exemple la couleur? Peut-être quelque chose dans les styles? Ou encore plus spécifiquement dans la balise XML de vue elle-même?
développeur android

Je ne sais pas, aujourd'hui j'ai résolu ce problème et les réponses ci-dessus n'ont pas fonctionné comme j'avais besoin. Je suppose que la couleur peut être personnalisée dans les styles, mais certainement pas dans la vue.
Anrimian

1
C'est exactement le bon effet que je recherche. Au fait, pouvez-vous mentionner où trouver cet attribut, il ne semble pas être documenté.
Jack Wang

2
Répond à la question OP. Doit être marqué comme meilleure réponse. +1
Corbella

2
@MeysamHadigheh ?est un raccourci pour?attr/
musooff

47

Créez et définissez une ondulation pouvant être dessinée comme arrière-plan. Quelque chose comme ça.

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

C'est quelque chose dans mon code. Vous pouvez utiliser vos couleurs :)
Thomas R.

Comment utiliser le sélecteur par défaut au cas où il serait pré-Lollipop? En outre, utilise-t-il les mêmes couleurs que celle du numéroteur?
développeur android

2
Vous pouvez mettre l'ondulation drawable dans votre dossier drawables-v21. Et pour pre L, utilisez un simple état dessinable. Utilisez le même nom de fichier et placez-le dans le dossier drawable (par défaut).
Thomas R.

2
Vous pouvez également créer un style. Dans le dossier values-v21, créez un nouveau style et définissez le dessin d'ondulation comme arrière-plan. Et pour pre L, c'est à dire dans votre dossier de valeurs styles.xml mettez en arrière-plan l'attribut "selectableItemBackground" pour le même style.
Thomas R.

1
Si vous voulez la même couleur d'ondulation que les autres effets d'ondulation par défaut utilisés dans l'application, utilisez "? Attr / colorControlHighlight" comme couleur.
alexbchr

27

Ajoutez simplement cet arrière-plan à votre vue

android:background=?android:attr/actionBarItemBackground


19

Vous pouvez créer des ondulations de cercle pouvant être dessinées à l'aide de l' android:radiusattribut en XML.

Exemple:

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

Faites attention, que votre your_radiusdoit être inférieure à la largeur et à la hauteur de votre vue. Par exemple: si vous avez une vue avec la taille 60dp x 60dp your_radiusdoit être proche 30dp(largeur / 2 ou hauteur / 2).

Travaillez sur Android 5.0 et supérieur.


3

Si vous voulez des fichiers XML plus génériques, j'ai deux fichiers:

1) btn_ripple_background avec le code:

<?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 avec code:

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

enfin l'utilisation:android:foreground="@drawable/ripple_btn_background"


2

Si vous voulez un effet d'entraînement qui ne traversera pas la limite du cercle, vous pouvez vérifier ce code. Cela fonctionne parfaitement pour moi. N'oubliez pas que vous devez donner id = @ android: id / mask dans 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

Essayer:

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

1
Veuillez ne pas publier uniquement le code comme réponse, mais inclure une explication de ce que fait votre code et de la manière dont il résout le problème de la question. Les réponses avec une explication sont généralement de meilleure qualité et sont plus susceptibles d'attirer des votes positifs.
Mark Rotteveel

Plus fluide que de définir actionBarItemBackground comme arrière-plan. Mais toujours pas exactement la même chose que l'animation de la barre d'action elle-même.
coolcool1994


0

Dans Kotlin / Java, vous pouvez faire ce qui suit

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
}


@RahulMandaliya merci pour le commentaire. Mon mauvais, c'était ma méthode d'extension personnalisée. Ajouté à la réponse
mihails.kuzmins
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.