Dibujable en forma con seleccionableItemBackground como fondo

2 minutos de lectura

Avatar de usuario de Zhen Liu
zhen liu

Tengo un par de botones que necesito un borde ovalado.

Así que tengo esto en un Capsule_border.xml

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <corners android:radius="9999dp"/>
    <stroke
        android:width="1px"
        android:color="@color/border_gray" />
</shape>

y yo usaría android:background="@drawable/capsule_border.xml donde lo necesito

Ahora, me gustaría tener un botón para tener este borde ovalado, pero también un android:background="?selectableItemBackground" para la retroalimentación visual.

Traté de usar un diseño principal con el fondo del elemento seleccionable y el botón con Capsule_border. Pero parece que el área en la que se puede hacer clic que se resalta es todo el cuadrado. En lugar de solo el área dentro del borde de la cápsula.

ingrese la descripción de la imagen aquí

¿Hay alguna manera de que pueda hacer que el fondo del elemento seleccionable no ocupe mucho todo el rectángulo de la vista, sino solo dentro del borde que dibuje?

avatar de usuario de azizbekian
azizbekian

Teniendo esquinas_redondas.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">
    <solid android:color="@android:color/transparent"/>
    <corners android:radius="15dp" />
    <stroke
        android:width="1px"
        android:color="#000000" />
</shape>

Y mi_ripple.xml:

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
        android:color="?android:attr/colorControlHighlight">
    <item android:id="@android:id/mask">
        <shape android:shape="rectangle">
            <solid android:color="#000000" />
            <corners android:radius="15dp" />
        </shape>
    </item>
    <item android:drawable="@drawable/round_corners" />
</ripple>

Y botón:

<Button
    android:background="@drawable/my_ripple"
    ... />

Dará como resultado esto:

ingrese la descripción de la imagen aquí

Ver este artículo.

  • Es realmente bueno. Hubiera sido mejor si hubiera una versión de nivel

    – Zhen Liu

    07/04/2017 a las 20:32

  • ¡Bendito seas por esto!

    – parodia

    22 de junio de 2021 a las 6:28

Avatar de usuario de Sam Chen
sam chen

Tengo una versión más simple de la primera respuesta:

<ripple
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="?colorControlHighlight"> <!-- default ripple color -->

    <item>
        <!-- the background shape when it's not being clicked -->
        <shape android:shape="rectangle">
            <solid android:color="@color/colorPrimary" />
            <corners android:radius="32dp" />
        </shape>
    </item>
</ripple>

Solo aplíquelo como fondo pero recuerde ELIMINAR LA SOMBRA si se aplica a Button:

style="?borderlessButtonStyle"

¡Buena suerte!


ingrese la descripción de la imagen aquí

  • ¿Cuál es la versión mínima de Android para esta solución?

    – Zhen Liu

    11 de febrero de 2020 a las 17:49

  • @Zhen Liu No veo ningún requisito de nivel de API, supongo que es bueno para todas las versiones.

    – Sam Chen

    11 de febrero de 2020 a las 18:00

Aquí hay una solución más simple ahora en 2020 (API> = 21 porque estamos usando el ?attr sintaxis):

<ripple
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="?colorControlHighlight">
    <!-- 🡡 the ripple's color (1) -->

    <!-- 🡣 no `id` so our <shape> will be drawn and not just used as mask -->
    <item>
        <shape>
            <corners android:radius="9dp" />
            <solid android:color="@color/white" />
        </shape>
    </item>

</ripple>

(1) Si no anulas colorControlHighlight en su tema, el color de la ondulación será el predeterminado de Android. Si usted hacer anularlo pero aún desea usar el uso predeterminado de Android ?android:colorControlHighlight en cambio

  • Este enfoque funciona, pero tiene el problema de que siempre dibuja un color de fondo (blanco en este caso) cuando no se hace clic en el elemento. Esto provoca un sobregiro. Por otro lado, usando una máscara podemos tener un fondo transparente por defecto y evitar que se sobredibuje.

    – jmart

    18 de junio de 2020 a las 14:46


  • @flaw simplemente elimine la línea continua y use backgroundTint. Esta debería ser la respuesta número 1 en 2021 debido al efecto dominó del nuevo sistema

    – Joao

    5 de octubre de 2021 a las 6:51


  • Mejor solución para 2021

    – DAVE SUCIO

    23 de noviembre de 2021 a las 21:20

¿Ha sido útil esta solución?