Comment créer des boutons standard sans bordure (comme dans le guide de conception mentionné)?

113

Je vérifiais juste les directives de conception et je m'interrogeais sur les boutons sans bordure. J'ai regardé et essayé de trouver la source, mais je ne peux pas la rassembler moi-même. Est-ce le widget Button normal mais vous ajoutez un style personnalisé (Android par défaut)? Comment rendre ces boutons sans bordure (bien sûr, vous pouvez définir l'arrière-plan sur vide, mais je n'ai pas de séparateur)?

Voici des liens vers les directives de conception:

entrez la description de l'image ici

KarlKarlsom
la source
Similaire stackoverflow.com/questions/14046232/…
Khaled Annajar

Réponses:

163

Pour dissiper une certaine confusion:

Cela se fait en 2 étapes: Définir l'attribut d'arrière-plan du bouton sur android: attr / selectableItemBackground vous crée un bouton avec des commentaires mais pas d'arrière-plan.

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

La ligne pour diviser le bouton sans bordure du reste de votre mise en page se fait par une vue avec l'arrière-plan android: attr / dividerVertical

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

Pour une meilleure compréhension, voici une mise en page pour une combinaison de boutons OK / Annuler sans bordure en bas de votre écran (comme dans l'image de droite ci-dessus).

<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>
KarlKarlsom
la source
25
À noter: cette solution ne fonctionne que pour le niveau d'API 11+.
9
Si vous utilisez HoloEverywhere, cela fonctionne pour le niveau d'API 7+. Vous devez changer ?android:attr/selectableItemBackgroundpour ?attr/selectableItemBackgroundet ?android:attr/dividerVerticalpour?attr/dividerVertical
Brais Gabin
1
?android:attr/dividerVerticalforet ?attr/dividerVerticalfonctionne également pour les abdominaux
oscarthecat
22

Réponse tardive, mais beaucoup de points de vue. Comme les API <11 ne sont pas encore mortes, pour ceux qui sont intéressés, voici une astuce.

Laissez votre contenant avoir la couleur désirée (peut être transparent). Ensuite, donnez à vos boutons un sélecteur avec une couleur transparente par défaut et une certaine couleur lorsque vous appuyez dessus. De cette façon, vous aurez un bouton transparent, mais changera de couleur lorsqu'il sera pressé (comme celui de holo). Vous pouvez également ajouter des animations (comme des holo). Le sélecteur devrait être quelque chose comme ceci:

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>

Et le bouton devrait avoir android:background="@drawable/selector_transparent_button"

PS: laissez-vous conteneur avoir les diviseurs ( android:divider='@android:drawable/...pour API <11)

PS [Newbies]: vous devez définir ces couleurs dans values ​​/ colors.xml

aacotroneo
la source
Cela a parfaitement fonctionné pour les deux API Level 10et API Level > 10!
theblang
C'est mieux que de le faire par programme, même si les deux fonctionneraient.
Eran Goldin
1
L'attribut "exitFadeDuration" n'est utilisé que dans l'API de niveau 11 et supérieur.
Bevor
oui @Bevor, gentil. Les lecteurs considèrent que les balises XML inconnues sont ignorées, donc il utilisera la décoloration pour api> = 11, et ne fonctionnera que pour <11
aacotroneo
18

Pour celui qui veut des boutons sans bordure mais toujours animés lorsqu'on clique dessus. Ajoutez ceci dans le bouton.

style="?android:attr/borderlessButtonStyle"

Si vous vouliez un séparateur / ligne entre eux. Ajoutez ceci dans la disposition linéaire.

style="?android:buttonBarStyle"

Résumé

<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>
aLIEz
la source
plus pour buttonBarStyle. et c'est la réponse btw.
frostymarvelous
7

Pour le style de matériau, ajoutez style="@style/Widget.AppCompat.Button.Borderless"lors de l'utilisation de la bibliothèque AppCompat.

Roel
la source
5

À partir de la source de l'application iosched, j'ai créé cette ButtonBarclasse:

/**
 * 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;
}

Ce sera le dans LinearLayoutlequel les boutons "OK" et "Annuler" entreront et se chargeront de les mettre dans l'ordre approprié. Ensuite, mettez ceci dans la disposition dans laquelle vous voulez les boutons:

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

Cela vous donne l'apparence de la boîte de dialogue avec des boutons sans bordure. Vous pouvez trouver ces attributs dans le res dans le framework. buttonBarStylefait le diviseur vertical et le remplissage. buttonBarButtonStyleest défini comme borderlessButtonStylepour le thème Holo, mais je pense que cela devrait être le moyen le plus robuste pour l'afficher lorsque le framework veut l'afficher.

Dandre Allison
la source
comment pourrais-je mettre ceci (? android: attr / buttonBarButtonStyle) dans styles.xml en tant qu'élément d'un style?
lis
4

Regardez dans le thème des attributs buttonBarStyle, buttonBarButtonStyleet borderlessButtonStyle.

Josh Lee
la source
Si j'utilise buttonBarButtonStylej'obtiens une exception Je 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}ne sais pas pourquoi, mais l'utilisation selectableItemBackgroundfonctionne à merveille.
Quelqu'un quelque part
4

Vous pouvez également créer des boutons sans bordure via le code:

TypedValue value= new TypedValue();
getApplicationContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground, value, true);
 myButton.setBackgroundResource(value.resourceId);
Isj
la source
Cela fonctionne, merci. Mais android.R.attr.selectableItemBackgroundnécessite l'API 21. Une idée comment faire cela sur les versions antérieures?
arenaq
Ça ne fonctionne pas. J'essaie de définir la ressource de android.R.attr.buttonBarButtonStyle et il dit que la ressource ne peut pas être trouvée.
Kristy Welsh
utilisez android.R.attr.selectableItemBackground
Isj
2

Pour ceux qui souhaitent créer un bouton sans bordure par programme pour les 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);
Sohail
la source
C'est mieux, plus simple que la solution de lsj. Just setBackgroundResource (0)
jk7
2

Une autre solution qui devrait fonctionner sur les plates-formes Android plus anciennes et plus récentes consiste à utiliser

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

attribut pour la vue Button. Mais après avoir ajouté le bouton de ligne ci-dessus ne fournira pas de retour tactile.

Pour fournir des commentaires tactiles, ajoutez le code suivant à la classe d'activité

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;
    }
});

Cela fonctionne bien pour moi.

prodev
la source
J'ajouterais également case MotionEvent.ACTION_CANCEL: ci-dessous case MotionEvent.ACTION_UP: .
Medo
2

Pour tous ceux qui recherchent encore:

héritez de votre propre style pour les barres de boutons Holo:

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

ou Holo Light:

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

et pour les boutons Holo sans bordure:

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

ou Holo Light:

<style name="yourStyle" parent="@android:style/Widget.Holo.Light.Button.Borderless.Small">
  ...
</style>
argenté
la source
2

Voici comment créer un bouton sans bordure (plat) par programme sans utiliser 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);
Manuel
la source
J'utilisais: ContextThemeWrapper myContext = new ContextThemeWrapper(this.getActivity(), R.style.Widget_AppCompat_Button_Borderless_Colored); Button myButton = new Button(myContext); et ça ne marcherait pas. Après avoir ajouté le 2ème et le 3ème paramètre, cela fonctionne!
levibostian
1

Utilisez le code ci-dessous dans votre fichier xml. Utilisez android: background = "# 00000000" pour avoir la couleur 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"
/>
Kayuri Ravrani
la source
1

Vous pouvez utiliser la bibliothèque de support AppCompat pour le bouton sans bordure.

Vous pouvez créer un bouton sans bordure comme ceci:

<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"/>

Vous pouvez créer un bouton coloré sans bordure comme ceci:

<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"/>
Rajesh
la source
0

Pour une raison quelconque, ni style="Widget.Holo.Button.Borderless"ni android:background="?android:attr/selectableItemBackground"travaillé pour moi. Pour être plus précis, a Widget.Holo.Button.Borderlessfait le travail sur Android 4.0 mais n'a pas fonctionné sur Android 2.3.3. Ce qui a fonctionné pour moi sur les deux versions était android:background="@drawable/transparent"et ce XML dans res / drawable / transparent.xml:

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

Tête simple à travers l'approche du mur.

Empereur Orionii
la source
2
Définir l'arrière-plan sur @android: couleur / transparent a fonctionné pour moi, sans avoir besoin du fichier XML supplémentaire.
Nicolai Buch-Andersen
Cela n'inclut pas comment obtenir le diviseur.
Navarr
3
@Navarr selon la réponse de Blundell, le diviseur ne fait pas partie du "bouton sans bordure". Cela ne devrait pas non plus être dû au fait que les boutons et toute autre classe de vue ne doivent pas être informés des composants de l'interface graphique environnants. C'est la responsabilité du conteneur. Dans les commentaires sur la publication de Blundell, il y a un lien vers ce qui semble être la disposition des éléments de détail de contact ICS. Il y a une vue supplémentaire (avec l'identifiant vertical_divider) pour afficher le diviseur. Pas de solution prête à l'emploi pour les diviseurs automatiques, bien qu'il existe une android:background="?android:attr/dividerVertical"astuce intéressante .
Emperor Orionii
La question des OP faisait référence aux "Boutons sans bordure" d'Android UX, et dans tous les exemples, ils ont le diviseur - qui fait apparemment partie de buttonBarStyle. Bien que vous m'ayez donné des informations très utiles, merci.
Navarr le
0

Un excellent diaporama sur la façon d'obtenir l'effet souhaité de Google Nick Butcher (commencez à la diapositive 20). Il utilise l'androïde standard @attrpour styliser le bouton et le séparateur.

Moritz
la source
Notez que les réponses liées uniquement aux liens sont déconseillées, les réponses SO devraient être le point final d'une recherche de solution (par rapport à une autre escale de références, qui ont tendance à devenir obsolètes avec le temps). Veuillez envisager d'ajouter un synopsis autonome ici, en gardant le lien comme référence.
kleopatra
0

En plus de la réponse du haut, vous pouvez également utiliser des vues avec une couleur d'arrière-plan gris foncé dans une mise en page linéaire comme celle-ci.

<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 votre ligne est horizontale, vous voudrez définir la hauteur sur 1dip et la largeur pour correspondre au parent et vice-versa si votre ligne est verticale.

Munaz
la source
0

Si vous souhaitez obtenir le même résultat par programme:

(c'est C # mais facilement transposable en Java)

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

Rencontre

    <Button
       style="@style/Widget.AppCompat.Button.Borderless.Colored"
    .../>
Yohan Dahmani
la source
0

Essayez ce code, pour supprimer l'arrière-plan dessinable (@ drawable / bg) par programme, il suffit de fournir null comme paramètre.

Button btn= new Button(this);
btn.setText("HI");
btn.setBackground(null);
Ramesh Kumar
la source
1
Merci pour cet extrait de code, qui pourrait fournir une aide limitée et immédiate. Une explication appropriée améliorerait considérablement sa valeur à long terme en montrant pourquoi c'est une bonne solution au problème et la rendrait plus utile aux futurs lecteurs avec d'autres questions similaires. Veuillez modifier votre réponse pour ajouter des explications, y compris les hypothèses que vous avez formulées.
NOhs