web-dev-qa-db-fra.com

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 bordures supérieure et inférieure. J'ai essayé d'ajouter Android:drawableTop et Android:drawableBottom à TextView, mais cela n'a fait que noircir l'intégralité de la vue.

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

358
emmby

Dans Android 2.2, vous pouvez effectuer les opérations suivantes. 

Créez un fichier XML dessinable tel que /res/drawable/textlines.xml et affectez-le en tant que propriété d'arrière-plan de 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 d'arrière-plan opaque, car les transparences ne fonctionneront pas. (Au moins, je pensais qu'ils l'avaient fait mais je me suis trompé). Dans l'exemple ci-dessus, vous pouvez voir que la couleur unie de la première forme #FFdddddd est copiée dans la couleur de trait des secondes formes.

393
Emile

J'ai utilisé une astuce pour que la bordure soit affichée à l'extérieur du conteneur. Avec cette astuce, seule une ligne est tracée afin que l'arrière-plan de la vue sous-jacente soit 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>
255
user1051892

Option 1: forme dessinable

C'est l'option la plus simple si vous souhaitez une bordure autour d'une disposition ou d'une vue dans laquelle vous pouvez définir l'arrière-plan. Créez un fichier XML dans le dossier drawable qui ressemble à 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 supprimer la solid si vous ne voulez pas de remplissage. L'ensemble background="@drawable/your_shape_drawable" sur votre présentation/vue.

Option 2: vue d'arrière-plan

Voici un petit truc que j'ai utilisé dans un RelativeLayout. En gros, vous avez un carré noir sous la vue pour lequel vous voulez donner une bordure, puis un peu de marge (pas de marge!) Pour que la vue apparaisse de telle sorte que le carré noir soit visible sur les bords.

Évidemment, cela ne fonctionne correctement que si la vue ne comporte aucune zone transparente. Si c'est le cas, je vous recommanderais d'écrire une variable BorderView personnalisée qui ne dessine que la bordure - il ne devrait s'agir que de 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 le demandez, il fonctionne fonctionne avec adjustViewBounds=true. Cependant, cela ne fonctionne pas si vous voulez avoir un arrière-plan dans une RelativeLayout entière, car un bogue empêche de remplir une RelativeLayout avec une View. Dans ce cas, je recommanderais la Shape drawable.

Option 3: 9-patch

Une dernière option consiste à utiliser un patch de 9 patchs comme celui-ci:

Vous pouvez l'utiliser sur n'importe quelle vue où vous pouvez définir Android:background="@drawable/...". Et oui, il faut que ce soit 6x6 - j'ai essayé 5x5 et cela n'a pas fonctionné.

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 les faire avec la variable Shape tirable, 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 ne voulez que des frontières au-dessus et au-dessous de votre vue. Vous pouvez placer votre vue dans une LinearLayout verticale (si ce n’est pas déjà fait), puis ajouter une Views vide au-dessus et au-dessous, comme ceci:

<View Android:background="#000" Android:layout_width="match_parent" Android:layout_height="1px"/>
94
Timmmm

Pour ajouter une bordure blanche 1dp en bas uniquement et pour avoir un arrière-plan transparent, vous pouvez utiliser les éléments suivants, qui sont plus simples que la plupart des réponses fournies ici.

Pour la vue TextView ou autre, ajoutez:

Android:background="@drawable/borderbottom"

Et dans le répertoire drawable, ajoutez le code XML suivant, appelé borderbottom.xml

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

Si vous voulez une bordure en haut, changez le Android:top="-2dp" en Android:bottom="-2dp"

La couleur n'a pas besoin d'être blanche et l'arrière-plan n'a pas non plus besoin d'être transparent.

L'élément solid peut ne pas être requis. Cela dépendra de votre conception (merci V. Kalyuzhnyu).

Fondamentalement, ce XML créera une bordure à l'aide de la forme rectangle, mais poussera ensuite les côtés supérieur, droit et gauche au-delà de la zone de rendu de la forme. Cela ne laisse que la bordure inférieure visible.

72
Tigger

Je voulais donc faire quelque chose de légèrement différent: une bordure au bas UNIQUEMENT, pour simuler un diviseur ListView. J'ai modifié la réponse de Piet Delport et 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 que vous utilisez px au lieu de dp pour obtenir exactement un diviseur de 1 pixel (certains DPI du téléphone feront disparaître une ligne de 1dp).

35
phreakhead

La réponse actuellement acceptée ne fonctionne pas. L'anti-aliasing crée des bordures verticales fines à gauche et à droite de la vue.

Cette version fonctionne parfaitement. Il vous permet également de définir indépendamment la largeur des bordures et vous pouvez également ajouter des bordures à gauche/à droite si vous le souhaitez. Le seul inconvénient est qu'il ne supporte PAS la transparence.

Créez un fichier XML nommable /res/drawable/top_bottom_borders.xml avec le code ci-dessous et affectez-le comme propriété d'arrière-plan de TextView. 

<?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="#DDDD00" /> <!-- border color -->
        </shape>
    </item>

    <item
        Android:bottom="1dp" 
        Android:top="1dp">   <!-- adjust borders width here -->
        <shape Android:shape="rectangle">
            <solid Android:color="#FFFFFF" />  <!-- background color -->
        </shape>
    </item>
</layer-list>

Testé sur Android KitKat via Marshmallow

34
gregschlom

Comme @Nic Hubbard l'a dit, il existe un moyen très simple d'ajouter une ligne de bordure.

<View
    Android:layout_width="match_parent"
    Android:layout_height="2dp"
    Android:background="#000000" >
</View>

Vous pouvez modifier la hauteur et la couleur de fond comme vous le souhaitez.

8
MattZ

Mes réponses sont basées sur la version @ Emmile mais j'utilise une couleur transparente au lieu de solide.
Cet exemple dessine 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 de l'arrière-plan sur lequel vous dessinez votre vue avec une bordure.

Si vous souhaitez modifier la position de la bordure, modifiez le décalage avec l'un des éléments suivants:

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

ou combinez-les pour avoir 2 bordures ou plus:

Android:bottom="2dp" Android:top="2dp"
7
vovahost

Vous pouvez également envelopper la vue dans un FrameLayout, puis définir la couleur d'arrière-plan et le remplissage du cadre à votre choix. Cependant, par défaut, la vue texte a un arrière-plan «transparent», vous devez donc également changer la couleur de fond de la vue.

7
okaram

Pourquoi ne pas simplement créer une vue haute 1dp avec une couleur de fond? Ensuite, il peut être facilement placé où vous voulez.

5
Nic Hubbard

Pour changer cela:

<TextView
    Android:text="My text"
    Android:background="@drawable/top_bottom_border"/>

Je préfère cette approche dans "drawable/top_bottom_border.xml": 

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <item>
        <shape>
            <gradient
                Android:angle="270"
                Android:startColor="#000"
                Android:centerColor="@Android:color/transparent"
                Android:centerX="0.01" />
        </shape>
    </item>
    <item>
        <shape>
            <gradient
                Android:angle="90"
                Android:startColor="#000"
                Android:centerColor="@Android:color/transparent"
                Android:centerX="0.01" />
        </shape>
    </item>
</layer-list>

Cela crée uniquement les bordures, pas un rectangle qui apparaîtra si votre arrière-plan a une couleur.

4
Dinidiniz

Commencez par créer un fichier xml avec le contenu indiqué ci-dessous, nommez-le border.xml et placez-le dans le dossier layout dans le répertoire res.

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <stroke Android:width="1dp" Android:color="#0000" />
    <padding Android:left="0dp" Android:top="1dp" Android:right="0dp"
        Android:bottom="1dp" />
</shape>

Après cela, dans le code utiliser

TextView tv = (TextView)findElementById(R.id.yourTextView);
tv.setBackgroundResource(R.layout.border);

Cela créera une ligne noire en haut et en bas de TextView.

4
Nikhil Dinesh

Notez ci-dessous le code

<View
    Android:layout_width="wrap_content"
    Android:layout_height="2dip"
    Android:layout_below="@+id/topics_text"
    Android:layout_marginTop="7dp"
    Android:layout_margin="10dp"
    Android:background="#ffffff" />
3
Abhi

Juste pour ajouter ma solution à la liste.

Je voulais une bordure inférieure semi-transparente qui dépasse la forme d'origine (la bordure semi-transparente était donc à l'extérieur le rectangle parent).

<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android" >
  <item>
    <shape Android:shape="rectangle" >      
      <solid Android:color="#33000000" /> <!-- Border colour -->
    </shape>
  </item>
  <item  Android:bottom="2dp" >
    <shape Android:shape="rectangle" >     
      <solid Android:color="#164586" />
    </shape>
  </item>
</layer-list>

Ce qui me donne;

enter image description here

3
Cadab

Ajoutez simplement des vues en haut et en bas de la View 

<?xml version="1.0" encoding="utf-8"?>
<Android.support.constraint.ConstraintLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">

    <View
        Android:layout_width="match_parent"
        Android:layout_height="1dp"
        Android:background="@color/your_color"
        app:layout_constraintBottom_toTopOf="@+id/textView"
        app:layout_constraintEnd_toEndOf="@+id/textView"
        app:layout_constraintStart_toStartOf="@+id/textView" />

    <TextView
        Android:id="@+id/textView"
        Android:layout_width="0dp"
        Android:layout_height="wrap_content"
        Android:layout_marginTop="32dp"
        Android:gravity="center"
        Android:text="Testing"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <View
        Android:layout_width="match_parent"
        Android:layout_height="1dp"
        Android:background="@color/your_color"
        app:layout_constraintEnd_toEndOf="@+id/textView"
        app:layout_constraintStart_toStartOf="@+id/textView"
        app:layout_constraintTop_toBottomOf="@+id/textView" />

</Android.support.constraint.ConstraintLayout>
1
Levon Petrosyan

Essayez d’envelopper l’image avec une image linéaire et de définir l’arrière-plan sur la couleur de bordure souhaitée du texte. Ensuite, définissez le remplissage de la vue texte sur l’épaisseur souhaitée pour votre bordure.

1
Matt

Vous pouvez également utiliser un chemin 9 pour faire votre travail. Créez-le pour que les pixels colorés ne se multiplient pas en hauteur mais uniquement le pixel transparent.

1
Kowlown

Voici un moyen d'y parvenir.

    <?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="@color/grey_coaching_text" />
            </shape>
        </item>

        <item
            Android:bottom="1dp"
            Android:top="1dp">
            <shape Android:shape="rectangle">
                <solid Android:color="@color/white" />
            </shape>
        </item>
    </layer-list>

Premier élément pour le trait et deuxième pour le fond solide. Cacher les frontières gauche et droite.

0
Kavya Shravan
// Just simply add border around the image view or view

<ImageView
                Android:id="@+id/imageView2"
                Android:layout_width="90dp"
                Android:layout_height="70dp"
                Android:layout_centerVertical="true"
                Android:layout_marginRight="10dp"
                Android:layout_toLeftOf="@+id/imageView1"
                Android:background="@Android:color/white"
                Android:padding="5dip" />

// After that dynamically put color into your view or image view object

objView.setBackgroundColor(Color.GREEN);

//VinodJ/Abhishek
0
Vinod Joshi
<TextView
    Android:id="@+id/textView3"
    Android:layout_width="match_parent"
    Android:layout_height="2dp"
    Android:background="#72cdf4"
    Android:text=" aa" />

Ajoutez simplement cette TextView sous le texte à l'endroit où vous souhaitez ajouter la bordure

0
Aquib Maniyar
<shape xmlns:Android="http://schemas.Android.com/apk/res/Android">

<solid Android:color="@color/light_grey1" />
<stroke
    Android:width="1dip"
    Android:color="@color/light_grey1" />

<corners
    Android:bottomLeftRadius="0dp"
    Android:bottomRightRadius="0dp"
    Android:topLeftRadius="5dp"
    Android:topRightRadius="5dp" />

    </shape>
0
Vinoj Vetha

Le moyen le plus simple d’ajouter des bordures pour insérer des bordures à l’aide de InsetDrawable, suivra uniquement avec la bordure supérieure:

<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:insetBottom="-2dp"
    Android:insetLeft="-2dp"
    Android:insetRight="-2dp">
    <shape Android:shape="rectangle">

        <solid Android:color="@color/light_gray" />
        <stroke
            Android:width=".5dp"
            Android:color="@color/dark_gray" />
    </shape>
</inset>
0
Zaid Mirza