424 votes

Existe-t-il un moyen simple d'ajouter une bordure en haut et en bas d'une vue Android ?

J'ai un TextView et j'aimerais ajouter une bordure noire le long de ses bords supérieur et inférieur. J'ai essayé d'ajouter android:drawableTop y android:drawableBottom au TextView, mais cela n'a fait que rendre la vue entière noire.

<TextView
    android:background="@android:color/green"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:drawableTop="@android:color/black"
    android:drawableBottom="@android:color/black"
    android:text="la la la" />

Existe-t-il un moyen d'ajouter facilement une bordure supérieure et inférieure à une vue (en particulier, un TextView) dans Android ?

2 votes

C'est surprenant que personne n'ait mentionné dividerVertical ! C'est la chose créée par Android, pour réaliser, eh bien, des séparateurs verticaux. Rien de plus facile et vous faites tout dans le panneau WYSIWYG "Design" d'Android Studio.

0 votes

La note dividerVertical a été implémentée dans l'API 11.

1 votes

Peut-être pouvez-vous montrer comment utiliser dividerVertical ?

448voto

Emile Points 4660

Dans Android 2.2, vous pouviez faire ce qui suit.

Créez une table traçable xml telle que /res/drawable/textlines.xml et attribuez-la comme propriété d'arrière-plan d'un TextView.

<TextView
android:text="My text with lines above and below"
android:background="@drawable/textlines"
/>

/res/drawable/textlines.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item>
      <shape 
        android:shape="rectangle">
            <stroke android:width="1dp" android:color="#FF000000" />
            <solid android:color="#FFDDDDDD" />

        </shape>
   </item>

   <item android:top="1dp" android:bottom="1dp"> 
      <shape 
        android:shape="rectangle">
            <stroke android:width="1dp" android:color="#FFDDDDDD" />
            <solid android:color="#00000000" />
        </shape>
   </item>

</layer-list>

L'inconvénient est que vous devez spécifier une couleur de fond opaque, car les transparents ne fonctionneront pas. (Du moins, je le croyais, mais je me suis trompé). Dans l'exemple ci-dessus, vous pouvez voir que la couleur solide de la première forme #FFdddddd est copiée dans la couleur du trait de la deuxième forme.

11 votes

Consultez également cette solution, qui fonctionne également pour les TextViews, si vous souhaitez une bordure tout autour : stackoverflow.com/questions/3263611/

26 votes

Essayez d'utiliser android:color="@null" pour éviter le problème de l'arrière-plan opaque.

0 votes

@emmby : lorsque je teste ce code sur une tablette, il met du temps à s'afficher à l'écran, après 1 seconde les bordures s'affichent lorsque je scrolle.

296voto

user1051892 Points 1264

J'ai utilisé une astuce pour que la bordure soit affichée à l'extérieur du conteneur. Avec cette astuce, seule une ligne est dessinée et l'arrière-plan de la vue sous-jacente est affiché.

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item
        android:bottom="1dp"
        android:left="-2dp"
        android:right="-2dp"
        android:top="-2dp">
        <shape android:shape="rectangle" >
            <stroke
                android:width="1dp"
                android:color="#FF000000" />

            <solid android:color="#00FFFFFF" />

            <padding android:left="10dp"
                android:right="10dp"
                android:top="10dp"
                android:bottom="10dp" />
        </shape>
    </item>

</layer-list>

3 votes

Cela a bien fonctionné pour moi, avec quelques modifications pour rendre la ligne un peu plus fine.

2 votes

Très belle astuce, même s'il serait plus agréable de ne pas avoir à tromper l'ordinateur pour faire avancer les choses.

0 votes

Bien fait ! Ce que vous devriez regarder est la gauche de l'élément, le haut, la droite, le bas devrait -(largeur du trait)dp

101voto

Timmmm Points 9909

Option 1 : Forme dessinable

C'est l'option la plus simple si vous voulez une bordure autour d'une mise en page ou d'une vue dans laquelle vous pouvez définir l'arrière-plan. Créez un fichier XML dans le répertoire drawable qui ressemble à quelque chose comme ceci :

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >

    <solid android:color="#8fff93" />

    <stroke
        android:width="1px"
        android:color="#000" />

</shape>

Vous pouvez retirer le solid si vous ne voulez pas de remplissage. L'ensemble background="@drawable/your_shape_drawable" sur votre disposition/vue.

Option 2 : Vue d'arrière-plan

Voici une petite astuce que j'ai utilisée dans un RelativeLayout . En gros, vous placez un carré noir sous la vue que vous voulez border, puis vous donnez à cette vue un peu de rembourrage (pas de marge !) pour que le carré noir soit visible sur les bords.

Évidemment, cela ne fonctionne correctement que si la vue n'a pas de zones transparentes. Si c'est le cas, je vous recommande d'écrire un script personnalisé BorderView qui ne dessine que la bordure - cela ne devrait représenter que quelques dizaines de lignes de code.

<View
    android:id="@+id/border"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignBottom="@+id/image"
    android:layout_alignLeft="@+id/image"
    android:layout_alignRight="@+id/image"
    android:layout_alignTop="@+id/main_image"
    android:background="#000" />

<ImageView
    android:id="@+id/image"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_...
    android:padding="1px"
    android:src="@drawable/..." />

Si vous vous demandez, c'est hace travailler avec adjustViewBounds=true . Cependant, cela ne fonctionne pas si vous voulez avoir un arrière-plan dans un entier RelativeLayout parce qu'il y a un bug qui vous empêche de remplir une RelativeLayout avec un View . Dans ce cas, je recommande le Shape traçable.

Option 3 : 9-patch

Une dernière option consiste à utiliser un dessinable à 9 cases comme celui-ci :

Vous pouvez l'utiliser sur n'importe quelle vue où vous pouvez définir android:background="@drawable/..." . Et oui, il doit être 6x6 - j'ai essayé 5x5 et ça n'a pas marché.

L'inconvénient de cette méthode est que vous ne pouvez pas changer les couleurs très facilement, mais si vous voulez des bordures fantaisistes (par exemple, seulement une bordure en haut et en bas, comme dans cette question), vous ne pourrez peut-être pas le faire avec la fonction Shape drawable, ce qui n'est pas très puissant.

Option 4 : Vues supplémentaires

J'ai oublié de mentionner cette option très simple si vous souhaitez uniquement des bordures au-dessus et au-dessous de votre vue. Vous pouvez placer votre vue dans une fenêtre verticale LinearLayout (s'il ne l'est pas déjà) et ajoutez ensuite le fichier vide View au-dessus et en dessous comme ceci :

<View android:background="#000" android:layout_width="match_parent" android:layout_height="1px"/>

4 votes

9 patch et le drawable shape sont ok, mais je vous déconseille d'ajouter des views ou imageviews pour résoudre un tel problème. La raison en est que vous devriez supprimer le plus grand nombre possible de ces <éléments> de vos mises en page pour améliorer le redessin et l'animation des mises en page. Je les supprimerais immédiatement et mettrais en place une solution similaire à l'option 1 ou 2.

2 votes

@Emile C'est vrai, mais si vous utilisez une ListView personnalisée qui ne prend pas en charge les séparateurs, une simple vue suffit. L'impact sur les performances est pratiquement nul, surtout si vous veillez à limiter la profondeur de votre mise en page. Cela permet également de contourner les problèmes liés aux diviseurs de ListView sur les différents appareils (j'ai vu des appareils qui ignorent cette propriété).

0 votes

Vous pouvez également utiliser le modèle de visualisation efficace avec les listviews pour vous assurer de réduire le nombre d'appels à findViewByID, qui est souvent la cause des mauvaises performances des listes.

36voto

phreakhead Points 2265

J'ai donc voulu faire quelque chose de légèrement différent : une bordure sur le bas SEULEMENT, pour simuler un séparateur ListView. J'ai modifié la réponse de Piet Delport et j'ai obtenu ceci :

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
   <item>
      <shape 
        android:shape="rectangle">
            <solid android:color="@color/background_trans_light" />    

        </shape>
   </item>

    <!-- this mess is what we have to do to get a bottom border only. -->
   <item android:top="-2dp"
         android:left="-2dp"
         android:right="-2dp"
         android:bottom="1px"> 
      <shape 
        android:shape="rectangle">    
            <stroke android:width="1dp" android:color="@color/background_trans_mid" />
            <solid android:color="@null" />
        </shape>
   </item>

</layer-list>

Notez l'utilisation de px au lieu de dp pour obtenir un diviseur d'exactement 1 pixel (certains DPI de téléphone feront disparaître une ligne de 1dp).

2 votes

Mon cher ! Quelle est la valeur de "@color/background_trans_light" ?

0 votes

Merci @phreakhead, ça marche pour moi ! Pas de bordure en haut, à gauche ou à droite. C'est exactement ce dont j'avais besoin, merci !

3 votes

Pouvez-vous expliquer pourquoi lorsque vous mettez -2dp il disparaît et lorsque vous mettez -1dp il est toujours visible ? Merci !

8voto

vovahost Points 1123

Mes réponses sont basées sur la version de @Emile mais j'utilise une couleur transparente au lieu d'une couleur solide.
Cet exemple va dessiner une bordure inférieure de 2dp.

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item>
        <shape android:shape="rectangle" >
            <stroke  android:width="2dp"
                     android:color="#50C0E9" />
            <solid android:color="@android:color/transparent" />
        </shape>
    </item>
    <item  android:bottom="2dp" >
        <shape android:shape="rectangle" >
            <stroke  android:width="2dp"
                     android:color="@color/bgcolor" />
            <solid android:color="@android:color/transparent" />
        </shape>
    </item>
</layer-list>

@color/bgcolor est la couleur du fond sur lequel vous dessinez votre vue avec une bordure.

Si vous voulez changer la position de la bordure, changez le décalage avec l'un des éléments suivants :

android:bottom="2dp"
android:top="2dp"
android:right="2dp"
android:left="2dp"

ou les combiner pour avoir 2 ou plusieurs bordures :

android:bottom="2dp" android:top="2dp"

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X