¿Cómo hacer una ondulación circular en un botón cuando se hace clic en él?


121

Antecedentes

En la aplicación de marcador de Android, cuando comienzas a buscar algo y haces clic en el botón de flecha a la izquierda de EditText, obtienes un efecto dominó circular en él:

ingrese la descripción de la imagen aquí

El problema

Intenté tenerlo también, pero obtuve uno rectangular:

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

¿Cómo hago para que el botón tenga un efecto de onda circular al hacer clic? ¿Tengo que crear un nuevo dibujable o hay una forma incorporada para eso?



la posible respuesta está aquí stackoverflow.com/questions/33477025/…
Amrish Kakadiya

1
Considere cambiar su respuesta seleccionada por la que tenga más votos positivos, ya que en realidad resuelve el problema
Jeff Barger

@JeffBarger ¿Por qué? Ambos funcionan bien. No hay nadie mejor entre ellos.
desarrollador de Android

Respuestas:


17

Si ya tiene una imagen de fondo, aquí hay un ejemplo de una onda que parece cercana 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: (opacidad establecida al 10% sobre fondo blanco) 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>

285

Si está utilizando el tema AppCompat, puede establecer el fondo de la vista como:

android:background="?selectableItemBackgroundBorderless"

Esto agregará una ondulación circular en 21 y arriba y un fondo cuadrado en 21 por debajo.


Agradable. ¿Puedo también establecer el color de alguna manera?
desarrollador de Android

4
en API 23, el fondo 'up' parece tener la mitad del tamaño en comparación con selectbleItemBackgroundBorderless
snodnipper

3
Bonita, la mejor respuesta. ty
Skywalker

1
@androiddeveloper, el color se puede configurar configurando colorControlHighlight como se muestra a continuación en su styles.xml <item name = "colorControlHighlight"> # F00 </item>
enlace

3
Si lo está utilizando dentro de otros diseños, es posible que también necesite android:clipChildren="false"en los diseños para permitir que la animación se propague.
Tanasis

82

Otro atributo con efecto de onda redonda, especialmente para la barra de acción:

android:background="?actionBarItemBackground"

UPD : este atributo puede cambiar el color de la ondulación:

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

Pero tenga en cuenta que este atributo se aplica a todos los efectos dominó predeterminados.


¿Alguna forma de personalizarlo? ¿Por ejemplo el color? ¿Quizás algo en estilos? ¿O incluso más específicamente en la propia etiqueta XML de vista?
desarrollador de Android

No lo sé, hoy resolví este problema y las respuestas anteriores no funcionaron como necesitaba. Supongo que el color se puede personalizar en estilos, pero definitivamente no en la vista.
Anrimian

1
Este es exactamente el efecto correcto que estoy buscando. Por cierto, ¿puede mencionar dónde encontrar este atributo? Parece que no está documentado.
Jack Wang

2
Responde a la pregunta de OP. Debe marcarse como la mejor respuesta. +1
Corbella

2
@MeysamHadigheh ?es un atajo para?attr/
musooff

47

Cree y establezca una ondulación dibujable como fondo. Algo como esto.

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

Es algo en mi código. Puedes usar tus colores :)
Thomas R.

¿Cómo usaría el selector predeterminado en caso de que esté en pre-Lollipop? Además, ¿utiliza los mismos colores que el del marcador?
desarrollador de Android

2
Puede poner el dibujable ondulado en su carpeta drawables-v21. Y para pre L use un simple estado dibujable. Use el mismo nombre de archivo y colóquelo en la carpeta dibujable (predeterminada).
Thomas R.

2
También puedes crear un estilo. En la carpeta values-v21, cree un nuevo estilo y establezca la ondulación dibujable como fondo. Y para pre L, es decir, en su carpeta de valores styles.xml ponga como fondo el atributo "selectableItemBackground" para el mismo estilo.
Thomas R.

1
Si desea el mismo color de ondulación que los otros efectos de ondulación predeterminados utilizados en la aplicación, utilice "? Attr / colorControlHighlight" como color.
alexbchr

27

Simplemente agregue este fondo a su vista

android:background=?android:attr/actionBarItemBackground


18

Puede crear un dibujo de ondulación circular utilizando el android:radiusatributo en xml.

Ejemplo:

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

Preste atención, your_radiusdebe ser menor que el ancho y la altura de su vista. Por ejemplo: si tiene una vista con el tamaño 60dp x 60dp your_radiusdebe estar cerca 30dp(ancho / 2 o alto / 2).

Trabaja en Android 5.0 y superior.


3

Si desea archivos XML más genéricos, tengo dos archivos:

1) btn_ripple_background con código:

<?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 código:

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

finalmente el uso:android:foreground="@drawable/ripple_btn_background"


1

Tratar:

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

1
No publique solo código como respuesta, sino que incluya una explicación de lo que hace su código y cómo resuelve el problema de la pregunta. Las respuestas con una explicación son generalmente de mayor calidad y es más probable que atraigan votos positivos.
Mark Rotteveel

Más suave que establecer actionBarItemBackground como fondo. Pero aún no es exactamente igual que la animación de la barra de acción en sí.
coolcool1994

1

Si desea un efecto dominó que no cruce el límite del círculo, puede verificar este código. Funciona perfectamente para mí. Solo recuerde, debe ingresar id = @ android: id / mask en 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>


0

En Kotlin / Java puede hacer lo siguiente

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 no encontrado
Rahul Mandaliya

@RahulMandaliya gracias por el comentario. Mi mal, fue mi método de extensión personalizado. Se agregó a la respuesta
mihails.kuzmins
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.