¿Cómo crear botones sin bordes estándar (como en la guía de diseño mencionada)?


113

Solo estaba revisando las pautas de diseño y preguntándome sobre los botones sin bordes. Busqué con los ojos abiertos y traté de encontrar la fuente, pero no puedo reunirla por mí mismo. ¿Es este el widget de botón normal, pero agrega un estilo personalizado (predeterminado de Android)? ¿Cómo hacer estos botones sin bordes (por supuesto, puede configurar el fondo en vacío, pero luego no tengo el divisor)?

Aquí enlaces a las pautas de diseño:

ingrese la descripción de la imagen aquí


Respuestas:


163

Para aclarar alguna confusión:

Esto se hace en 2 pasos: Establecer el atributo de fondo del botón en android: attr / selectableItemBackground crea un botón con comentarios pero sin fondo.

android:background="?android:attr/selectableItemBackground"

La línea para dividir el botón sin bordes del resto de su diseño se realiza mediante una vista con el fondo android: attr / dividerVertical

android:background="?android:attr/dividerVertical"

Para una mejor comprensión, aquí hay un diseño para una combinación de botones sin bordes Aceptar / Cancelar en la parte inferior de la pantalla (como en la imagen de la derecha arriba).

<RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="48dp"
        android:layout_alignParentBottom="true">
        <View
            android:layout_width="match_parent"
            android:layout_height="1dip"
            android:layout_marginLeft="4dip"
            android:layout_marginRight="4dip"
            android:background="?android:attr/dividerVertical"
            android:layout_alignParentTop="true"/>
        <View
            android:id="@+id/ViewColorPickerHelper"
            android:layout_width="1dip"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_alignParentBottom="true"
            android:layout_marginBottom="4dip"
            android:layout_marginTop="4dip"
            android:background="?android:attr/dividerVertical" 
            android:layout_centerHorizontal="true"/>
        <Button
            android:id="@+id/BtnColorPickerCancel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true"
            android:layout_toLeftOf="@id/ViewColorPickerHelper"
            android:background="?android:attr/selectableItemBackground"
            android:text="@android:string/cancel" 
            android:layout_alignParentBottom="true"/>
        <Button
            android:id="@+id/BtnColorPickerOk"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_alignParentRight="true"
            android:layout_alignParentTop="true"
            android:background="?android:attr/selectableItemBackground"
            android:text="@android:string/ok" 
            android:layout_alignParentBottom="true" 
            android:layout_toRightOf="@id/ViewColorPickerHelper"/>
    </RelativeLayout>

25
Vale la pena señalar: esta solución solo funciona para API nivel 11+.

9
Si usa HoloEverywhere , funciona para API nivel 7+. Debe cambiar ?android:attr/selectableItemBackgroundpara ?attr/selectableItemBackgroundy ?android:attr/dividerVerticalpara?attr/dividerVertical
Brais Gabin

1
?android:attr/dividerVerticalfory ?attr/dividerVerticaltambién funciona para abdominales
oscarthecat


22

Respuesta tardía, pero muchas opiniones. Como las API <11 aún no están muertas, para los interesados ​​aquí hay un truco.

Deje que su recipiente tenga el color deseado (puede ser transparente). Luego, dale a tus botones un selector con color transparente predeterminado y algo de color cuando se presionan. De esa manera, tendrá un botón transparente, pero cambiará de color cuando lo presione (como el de holo). También puede agregar alguna animación (como holo's). El selector debería ser algo como esto:

res/drawable/selector_transparent_button.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" 
          android:exitFadeDuration="@android:integer/config_shortAnimTime">
     <item android:state_pressed="true"
         android:drawable="@color/blue" />

   <item android:drawable="@color/transparent" />
</selector>

Y el botón debería tener android:background="@drawable/selector_transparent_button"

PD: deja que tu contenedor tenga los divisores ( android:divider='@android:drawable/...para API <11)

PD [novatos]: debes definir esos colores en values ​​/ colors.xml


¡Esto funcionó perfectamente para ambos API Level 10y API Level > 10!
theblang

Esto es mejor que hacerlo mediante programación, aunque ambos funcionarían.
Eran Goldin

1
El atributo "exitFadeDuration" solo se usa en el nivel de API 11 y superior.
Bevor

sí @Bevor, bonito. Los lectores consideran que las etiquetas xml desconocidas se ignoran, por lo que usará el desvanecimiento para api> = 11, y solo funcionará para <11
aacotroneo

18

Para el que quiere botones sin bordes pero aún animados cuando se hace clic. Agregue esto en el botón.

style="?android:attr/borderlessButtonStyle"

Si quisieras un divisor / línea entre ellos. Agregue esto en el diseño lineal.

style="?android:buttonBarStyle"

Resumen

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:orientation="horizontal"
   style="?android:buttonBarStyle">

    <Button
        android:id="@+id/add"
        android:layout_weight="1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/add_dialog" 
        style="?android:attr/borderlessButtonStyle"
        />

    <Button
        android:id="@+id/cancel"
        android:layout_weight="1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/cancel_dialog" 
        style="?android:attr/borderlessButtonStyle"
        />

</LinearLayout>

más para buttonBarStyle. y esta es la respuesta por cierto.
frostymarvelous

7

Para el estilo del material, agregue style="@style/Widget.AppCompat.Button.Borderless"cuando use la biblioteca AppCompat.


5

De la fuente de la aplicación iosched se me ocurrió esta ButtonBarclase:

/**
 * An extremely simple {@link LinearLayout} descendant that simply reverses the 
 * order of its child views on Android 4.0+. The reason for this is that on 
 * Android 4.0+, negative buttons should be shown to the left of positive buttons.
 */
public class ButtonBar extends LinearLayout {

    public ButtonBar(Context context) {
        super(context);
    }

    public ButtonBar(Context context, AttributeSet attributes) {
        super(context, attributes);
    }

    public ButtonBar(Context context, AttributeSet attributes, int def_style) {
        super(context, attributes, def_style);
    }

    @Override
    public View getChildAt(int index) {
        if (_has_ics)
            // Flip the buttons so that "OK | Cancel" becomes "Cancel | OK" on ICS
            return super.getChildAt(getChildCount() - 1 - index);

        return super.getChildAt(index);
    }

    private final static boolean _has_ics = Build.VERSION.SDK_INT >= 
                                        Build.VERSION_CODES.ICE_CREAM_SANDWICH;
}

Este será el lugar al LinearLayoutque vayan los botones "Aceptar" y "Cancelar", y se encargará de ponerlos en el orden apropiado. Luego coloque esto en el diseño en el que desea los botones:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:divider="?android:attr/dividerHorizontal"
          android:orientation="vertical"
          android:showDividers="middle">
    <!--- A view, this approach only works with a single view here -->
    <your.package.ButtonBar style="?android:attr/buttonBarStyle"
        android:id="@+id/buttons"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:weightSum="1.0">
        <Button style="?android:attr/buttonBarButtonStyle"
            android:id="@+id/ok_button"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="0.5"
            android:text="@string/ok_button" />
        <Button style="?android:attr/buttonBarButtonStyle"
            android:id="@+id/cancel_button"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="0.5"
            android:text="@string/cancel_button" />
    </your.package.ButtonBar>
</LinearLayout>

Esto le da la apariencia de un diálogo con botones sin bordes. Puede encontrar estos atributos en el res en el marco. buttonBarStylehace el divisor vertical y el acolchado. buttonBarButtonStyleestá configurado como borderlessButtonStylepara el tema Holo, pero creo que esta debería ser la forma más sólida de mostrarlo como el marco quiere mostrarlo.


¿Cómo podría poner esto (? android: attr / buttonBarButtonStyle) en styles.xml como elemento de un estilo?
lis

4

Mirada en el tema de los atributos buttonBarStyle, buttonBarButtonStyley borderlessButtonStyle.


Si lo uso buttonBarButtonStyle, obtengo una excepción E/AndroidRuntime(17134): Caused by: java.lang.reflect.InvocationTargetException E/AndroidRuntime(17134): Caused by: android.content.res.Resources$NotFoundException: Resource is not a Drawable (color or path): TypedValue{t=0x1/d=0x1030281 a=2 r=0x1030281}No tengo idea de por qué, pero el uso selectableItemBackgroundfunciona de maravilla.
Someone Somewhere

4

También puede hacer que los botones no tengan bordes a través del código:

TypedValue value= new TypedValue();
getApplicationContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground, value, true);
 myButton.setBackgroundResource(value.resourceId);

Está funcionando, gracias. Pero android.R.attr.selectableItemBackgroundrequiere API 21. ¿Alguna idea de cómo hacer esto en versiones anteriores?
arenaq

No funciona. Estoy tratando de configurar el recurso de android.R.attr.buttonBarButtonStyle y dice que no se puede encontrar el recurso.
Kristy Welsh

use android.R.attr.selectableItemBackground
Isj

2

Para aquellos que quieren crear un botón sin bordes mediante programación para API> = 8

ImageButton smsImgBtn = new ImageButton(this);
//Sets a drawable as the content of this button
smsImgBtn.setImageResource(R.drawable.message_icon);    
//Set to 0 to remove the background or for bordeless button
smsImgBtn.setBackgroundResource(0);

Esto es mejor, más simple que la solución de lsj. Just setBackgroundResource (0)
jk7

2

Otra solución que debería funcionar tanto en plataformas Android antiguas como nuevas es usar

android:background="@android:color/transparent"

atributo para la vista Botón. Pero después de agregar el botón de línea anterior no proporcionará comentarios táctiles.

Para proporcionar comentarios táctiles, agregue el siguiente código a la clase de actividad

button.setOnTouchListener(new View.OnTouchListener() {          
    @Override
    public boolean onTouch(View view, MotionEvent event) {
        switch (event.getAction())
        {
            case MotionEvent.ACTION_DOWN:    
                ((Button)view).setBackgroundColor(Color.LTGRAY);
                break;
            case MotionEvent.ACTION_UP:
                ((Button)view).setBackgroundColor(Color.TRANSPARENT);
        }
        return false;
    }
});

esta trabajando bien para mi.


También agregaría case MotionEvent.ACTION_CANCEL: debajo del case MotionEvent.ACTION_UP: .
Medo

2

Para cualquiera que todavía esté buscando:

hereda su propio estilo para las barras de botones Holo:

<style name="yourStyle" parent="@android:style/Holo.ButtonBar">
  ...
</style>

o Holo Light:

<style name="yourStyle" parent="@android:style/Holo.Light.ButtonBar">
  ...
</style>

y para botones Holo sin bordes:

<style name="yourStyle" parent="@android:style/Widget.Holo.Button.Borderless.Small">
  ...
</style>

o Holo Light:

<style name="yourStyle" parent="@android:style/Widget.Holo.Light.Button.Borderless.Small">
  ...
</style>

2

Así es como se crea un botón sin bordes (plano) mediante programación sin usar XML

ContextThemeWrapper myContext = new ContextThemeWrapper(this.getActivity(), 
   R.style.Widget_AppCompat_Button_Borderless_Colored);

Button myButton = new Button(myContext, null, 
   R.style.Widget_AppCompat_Button_Borderless_Colored);

Estaba usando: ContextThemeWrapper myContext = new ContextThemeWrapper(this.getActivity(), R.style.Widget_AppCompat_Button_Borderless_Colored); Button myButton = new Button(myContext); y no funcionaría. Después de agregar el segundo y tercer parámetro, ¡está funcionando!
levibostian

1

Utilice el siguiente código en su archivo xml. Usa android: background = "# 00000000" para tener el color transparente.

<Button
   android:id="@+id/btnLocation"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:background="#00000000"
   android:text="@string/menu_location"
   android:paddingRight="7dp"
/>

1

Puede utilizar la biblioteca de compatibilidad de AppCompat para el botón sin bordes.

Puedes hacer un botón sin bordes como este:

<Button
    style="@style/Widget.AppCompat.Button.Borderless"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="16dp" 
    android:text="@string/borderless_button"/>

Puede hacer un botón de color sin bordes de esta manera:

<Button
    style="@style/Widget.AppCompat.Button.Borderless.Colored"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="16dp" 
    android:text="@string/borderless_colored_button"/>

0

Por alguna razón, ni style="Widget.Holo.Button.Borderless"ni android:background="?android:attr/selectableItemBackground"funcionó para mí. Para ser más precisos, Widget.Holo.Button.Borderlessfuncionó en Android 4.0 pero no funcionó en Android 2.3.3. Lo que me hizo el truco en ambas versiones fue android:background="@drawable/transparent"y este XML en res / drawable / transparent.xml:

<shape xmlns:android="http://schemas.android.com/apk/res/android" 
    android:shape="rectangle" >
</shape>

Cabeza llana a través del enfoque de la pared.


2
Establecer el fondo en @android: color / transparent funcionó para mí, sin la necesidad de un archivo XML adicional.
Nicolai Buch-Andersen

Esto no incluye cómo obtener el divisor.
Navarr

3
@Navarr de acuerdo con la respuesta de Blundell, el divisor no es parte del "botón sin bordes". Tampoco debería ser porque los botones y cualquier otra clase de vista no deberían estar informados sobre los componentes de la GUI circundantes. Esa es la responsabilidad del contenedor. En los comentarios a la publicación de Blundell hay un enlace a lo que parece ser el diseño del elemento de detalles de contacto de ICS. Hay una vista adicional (con id. Vertical_divider) para mostrar el divisor. No hay una solución lista para usar para los divisores automáticos, aunque hay un buen android:background="?android:attr/dividerVertical"truco.
Emperador Orionii

La pregunta de OP se refería a los "Botones sin bordes" de Android UX, y en todos los ejemplos tienen el divisor, que aparentemente es parte de buttonBarStyle. Aunque me ha dado información muy útil, gracias.
Navarr

0

Una gran presentación de diapositivas sobre cómo lograr el efecto deseado de Googles Nick Butcher (comience en la diapositiva 20). Utiliza el androide estándar @attrpara diseñar el botón y el divisor.


Tenga en cuenta que se desaconsejan las respuestas de solo enlace , las respuestas SO deben ser el punto final de la búsqueda de una solución (frente a otra escala de referencias, que tienden a quedarse obsoletas con el tiempo). Considere agregar una sinopsis independiente aquí, manteniendo el enlace como referencia.
kleopatra

0

Además de la respuesta superior, también puede usar vistas con un color de fondo gris oscuro en un diseño lineal como ese.

<View
    android:layout_width="match_parent"
    android:layout_height="1dip"
    android:layout_marginBottom="4dip"
    android:layout_marginLeft="4dip"
    android:layout_marginRight="4dip"
    android:layout_marginTop="4dip"
    android:background="@android:color/darker_gray"/>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="4dip"
    android:orientation="horizontal"
    android:weightSum="1">

    <Button
        android:id="@+id/button_decline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_weight="0.50"
        android:background="?android:attr/selectableItemBackground"
        android:padding="10dip"
        android:text="@string/decline"/>

    <View
        android:layout_width="1dip"
        android:layout_height="match_parent"
        android:layout_marginLeft="4dip"
        android:layout_marginRight="4dip"
        android:background="@android:color/darker_gray"/>

    <Button
        android:id="@+id/button_accept"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginRight="10dp"
        android:layout_weight="0.50"
        android:background="?android:attr/selectableItemBackground"
        android:padding="10dip"
        android:text="@string/accept"/>
</LinearLayout>

Si su línea es horizontal, querrá establecer la altura en 1 punto y el ancho para que coincida con el padre y viceversa si su línea es vertical.


0

Si desea lograr lo mismo mediante programación:

(esto es C # pero fácilmente transaccional a Java)

Button button = new Button(new ContextThemeWrapper(Context, Resource.Style.Widget_AppCompat_Button_Borderless_Colored), null, Resource.Style.Widget_AppCompat_Button_Borderless_Colored);

Partido

    <Button
       style="@style/Widget.AppCompat.Button.Borderless.Colored"
    .../>

0

Pruebe este código, para eliminar el elemento de diseño de fondo (@ drawable / bg) mediante programación, solo necesitamos proporcionar un valor nulo como parámetro.

Button btn= new Button(this);
btn.setText("HI");
btn.setBackground(null);

1
Gracias por este fragmento de código, que puede proporcionar ayuda inmediata y limitada. Una explicación adecuada mejoraría enormemente su valor a largo plazo al mostrar por qué es una buena solución al problema y lo haría más útil para futuros lectores con otras preguntas similares. Por favor, editar su respuesta a añadir un poco de explicación, incluyendo los supuestos realizados.
NOhs
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.