Ligne verticale utilisant XML drawable

162

J'essaie de comprendre comment définir une ligne verticale (1dp d'épaisseur) à utiliser comme dessinable.

Pour en faire un horizontal, c'est assez simple:

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="line">
    <stroke android:width="1dp" android:color="#0000FF"/>
    <size android:height="50dp" />     
</shape>

La question est: comment rendre cette ligne verticale?

Oui, il existe des solutions de contournement, telles que dessiner une forme de rectangle de 1px d'épaisseur, mais cela complique le XML dessinable, s'il se compose de plusieurs <item> éléments.

Quelqu'un a eu une chance avec ça?

METTRE À JOUR

L'affaire n'est toujours pas résolue. Cependant, pour quiconque participe à une croisade de documentation Android - vous pourriez trouver ceci utile: Manuel XML Android manquant

METTRE À JOUR

Je n'ai trouvé d'autre moyen que celui que j'ai marqué comme correct. Cela fait l'affaire mais semble un peu "lourd", donc si vous connaissez la réponse, n'oubliez pas de partager;)

Kaspa
la source

Réponses:

394

Au lieu d'une forme, vous pouvez essayer un View:

<View
    android:layout_width="1dp"
    android:layout_height="fill_parent"
    android:background="#FF0000FF" />

Je ne l'ai utilisé que pour les lignes horizontales, mais je pense que cela fonctionnerait également pour les lignes verticales.

Utilisation:

<View
    android:layout_width="fill_parent"
    android:layout_height="1dp"
    android:background="#FF0000FF" />

pour une ligne horizontale.

CommonsWare
la source
4
merci Mark :)! Je suis conscient que je peux utiliser une vue pour y parvenir. Le fait est que j'assemble une vue un peu plus complexe que je souhaite utiliser comme dessinable pour l'arrière-plan d'une cellule de tableau. Il existe différents types de formes / dégradés / lignes. Utiliser une vue SERAIT une solution, mais je devrais la mettre dans un "calque" de dessin différent et cela vous prend peut-être une balle dans le pied lorsque je vais rencontrer un redimensionnement, etc. Je me demande pourquoi il n'y a pas de documentation sur le " shape "xmls, peut-être que quelqu'un de Google pourrait nous éclairer? :)
Kaspa
1
L'utilisation de marginRight / Start et Left / End est également parfois intéressante pour obtenir de l'espace sur les côtés.
George
108

Vous pouvez imbriquer votre forme dans une balise de rotation.

<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromDegrees="90"
    android:toDegrees="90">
    <shape 
        android:shape="line">
        <stroke
            android:width="1dp"
            android:color="#ff00ff"
            android:dashWidth="1dp"
            android:dashGap="2dp" />
    </shape>
</rotate>

Cependant, le seul problème est que les paramètres de mise en page définis dans votre mise en page xml seront les dimensions utilisées pour dessiner la forme d'origine. Cela signifie que si vous voulez que votre ligne mesure 30dp, vous devez définir un layout_width de 30dp dans votre layout xml. Mais la largeur finale sera également de 30dp dans ce cas, ce qui est probablement indésirable dans la plupart des situations. Cela signifie essentiellement que la largeur et la hauteur doivent avoir la même valeur, la valeur de la longueur souhaitée pour la ligne. Je ne savais pas comment résoudre ce problème.

Cela semble être la solution «à la manière Android», mais à moins qu'il n'y ait une solution ou une solution de contournement pour le problème de dimensions que je mentionne, cela ne fonctionnera probablement pas pour la plupart des gens. Ce dont nous avons vraiment besoin, c'est d'un attribut d'orientation dans <shape /> ou <stroke />.

Vous pouvez également essayer de référencer un autre dessinable dans les attributs de la balise de rotation, tels que:

<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromDegrees="90"
    android:toDegrees="90"
    android:drawable="@drawable/horizontal_line" />

Cependant, je n'ai pas testé cela et je m'attends à ce qu'il ait les mêmes problèmes.

-- ÉDITER --

Oh, j'ai trouvé une solution. Vous pouvez utiliser une marge négative dans votre mise en page xml pour vous débarrasser de l'espace supplémentaire indésirable. Tel que:

<ImageView
    android:layout_width="35dp"
    android:layout_height="35dp"
    android:layout_marginLeft="-15dp"
    android:layout_marginRight="-15dp"
    android:src="@drawable/dashed_vertical_line" />
céphus
la source
4
alors que la marge négative fonctionnera pour 99% des appareils ... sachez simplement qu'il existe des appareils qui forceront la fermeture si vous faites cela. Certains appareils ont du mal à gonfler une marge négative
Kent Andersen
2
@cephus J'utilise votre premier code, mais j'ai besoin de la ligne en haut de la vue. C'est au centre de ma vision. Comment puis-je définir une gravité pour celui-ci (dans le fichier xml de forme)?
Behzad
20

Vous pouvez utiliser l'attribut de rotation

 <item>
    <rotate
        android:fromDegrees="90"
        android:toDegrees="90"
        android:pivotX="50%"
        android:pivotY="50%" >
        <shape
            android:shape="line"
            android:top="1dip" >
            <stroke
                android:width="1dip"
                 />
        </shape>
    </rotate>
</item>
user4679242
la source
6
C'est certainement une meilleure (ou la meilleure) réponse car, bien que la réponse de @ commonsware soit suffisante pour les lignes verticales normales. Si nous ne voulons pas créer de lignes pointillées (disons par exemple), c'est la seule réponse qui fonctionnerait correctement.
Subin Sebastian
16
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
  android:shape="rectangle" >
    <stroke android:width="1dp" android:color="@color/white" />
    <size android:width="2dp" />
</shape>

Travaille pour moi . Mettez-le comme arrière-plan de la vue avec fill_parent ou taille fixe en hauteur dp

logcat
la source
12

J'ai trouvé une solution différente. L'idée est de remplir d'abord le dessinable avec la couleur que vous aimez pour la ligne, puis de remplir à nouveau toute la zone avec la couleur d'arrière-plan tout en utilisant un rembourrage gauche ou droit. Évidemment, cela ne fonctionne que pour une ligne verticale à l'extrême gauche ou à droite de votre dessin.

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:drawable="@color/divider_color" />
    <item android:left="6dp" android:drawable="@color/background_color" />
</layer-list>
Eric Kok
la source
J'avais besoin d'un arrière-plan avec des bordures à gauche, à droite, en bas et cela a fonctionné pour moi, merci!
Andrii Chernenko
Génial, avec cela, j'ai réussi à créer des diviseurs soignés dans mon LinearLayout ( showDividers="middle"). Pour obtenir un diviseur 2dp, j'avais besoin de spécifier android:left="3dp"ici.
Jonik
Astuce: pour rendre ce dessin utile plus généralement, utilisez @android:color/transparentplutôt que le codage en dur @color/background_color.
Jonik
En fait, pour mes besoins en diviseur vertical, cette solution est encore plus simple . :)
Jonik
@Jonik Bien sûr, mais cela ne fonctionne qu'avec une vue à hauteur fixe, pas avec wrap_content.
Eric Kok
10

Je pense que c'est la solution la plus simple:

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

    <item
        android:gravity="center">
        <shape android:shape="rectangle">
            <size android:width="1dp" />
            <solid android:color="#0000FF" />
        </shape>
    </item>

</layer-list>
a.ch.
la source
Merveilleux. Ajoutez android:heightà sizesi vous souhaitez contrôler également cette dimension.
Giulio Piancastelli
4

J'avais besoin d'ajouter mes vues de manière dynamique / par programme, donc l'ajout d'une vue supplémentaire aurait été fastidieux. Ma hauteur de vue était WRAP_CONTENT, je ne pouvais donc pas utiliser la solution rectangle. J'ai trouvé un article de blog ici sur l'extension de TextView, le remplacement de onDraw () et la peinture dans la ligne, donc j'ai mis en œuvre cela et cela fonctionne bien. Voir mon code ci-dessous:

public class NoteTextView extends TextView {
    public NoteTextView(Context context) {
       super(context);
    }
    private Paint paint = new Paint();
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        paint.setColor(Color.parseColor("#F00000FF"));
        paint.setStrokeWidth(0);
        paint.setStyle(Paint.Style.FILL);
        canvas.drawLine(0, 0, 0, getHeight(), paint);
    }
}

J'avais besoin d'une ligne verticale sur la gauche, mais les paramètres de la drawLine(startX, startY, stopX, stopY, paint)ligne de dessin permettent de dessiner n'importe quelle ligne droite dans n'importe quelle direction de la vue. Ensuite, dans mon activité, j'espère que NoteTextView note = new NoteTextView(this); cela aide.

Willlma
la source
3

c'est très simple ... pour ajouter une ligne verticale dans android xml ...

<View
android:layout_width="fill_parent"
android:layout_height="1dp"
android:layout_marginTop="5dp"
android:rotation="90"
android:background="@android:color/darker_gray"/>
user3130068
la source
Cela fonctionne très bien lorsque vous ne pouvez pas utiliser fill_parent pour la hauteur car la hauteur du parent est définie sur wrap_content.
Sergey Aldoukhov
2

Cela dépend de l'endroit où vous voulez avoir la ligne verticale, mais si vous voulez une bordure verticale par exemple, vous pouvez avoir la vue parent avoir un arrière-plan un dessin personnalisé. Et vous pouvez ensuite définir le dessinable comme ceci:

<?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="#000000" />
            <solid android:color="#00ffffff" />

        </shape>
    </item>

    <item android:right="1dp">
        <shape android:shape="rectangle">
            <solid android:color="#00ffffff" />
        </shape>
    </item>

</layer-list>

Cet exemple créera une fine ligne noire de 1dp sur le côté droit de la vue, qui aura ce dessinable comme arrière-plan.

Lukas1
la source
2
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:bottom="-3dp"
        android:left="-3dp"
        android:top="-3dp">

        <shape android:shape="rectangle">
            <solid android:color="@color/colorPrimary" />
            <stroke
                android:width="2dp"
                android:color="#1fc78c" />
        </shape>

    </item>

</layer-list>
AnupamChugh
la source
2

Il semble que personne n'ait mentionné cette option:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:drawable="@color/white" android:width="1dp"/>
</layer-list>
Sergey Neskoromny
la source
1

Vous pouvez utiliser une forme mais au lieu d'une ligne, faites-en un rectangle.

android:shape="rectangle">
<stroke
    android:width="5dp"
    android:color="#ff000000"
    android:dashGap="10px"
    android:dashWidth="30px" />

et Dans votre mise en page, utilisez ceci ...

<ImageView
    android:layout_width="7dp"
    android:layout_height="match_parent"
    android:src="@drawable/dashline"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"
    android:layerType="software"/>

Vous devrez peut-être jouer avec la largeur, en fonction de la taille des tirets, pour la mettre en une seule ligne.

J'espère que cela aide Cheers

Boxlady
la source
1
add this in your styles.xml

        <style name="Divider">
            <item name="android:layout_width">1dip</item>
            <item name="android:layout_height">match_parent</item>
            <item name="android:background">@color/divider_color</item>
        </style>

        <style name="Divider_invisible">
            <item name="android:layout_width">1dip</item>
            <item name="android:layout_height">match_parent</item>
        </style>

then wrap this style in a linear layout where you want the vertical line, I used the vertical line as a column divider in my table. 

     <TableLayout
                android:id="@+id/table"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal"
                android:stretchColumns="*" >

                <TableRow
                    android:id="@+id/tableRow1"
                    android:layout_width="fill_parent"
                    android:layout_height="match_parent"
                    android:background="#92C94A" >

                    <TextView
                        android:id="@+id/textView11"
                        android:paddingBottom="10dp"
                        android:paddingLeft="5dp"
                        android:paddingRight="5dp"
                        android:paddingTop="10dp" />
    //...................................................................    

                    <LinearLayout
                        android:layout_width="1dp"
                        android:layout_height="match_parent" >

                        <View style="@style/Divider_invisible" />
                    </LinearLayout>
        //...................................................................
                    <TextView
                        android:id="@+id/textView12"
                        android:paddingBottom="10dp"
                        android:paddingLeft="5dp"
                        android:paddingRight="5dp"
                        android:paddingTop="10dp"
                        android:text="@string/main_wo_colon"
                        android:textColor="@color/white"
                        android:textSize="16sp" />
  //...............................................................  
                    <LinearLayout
                        android:layout_width="1dp"
                        android:layout_height="match_parent" >

                        <View style="@style/Divider" />
                    </LinearLayout>

    //...................................................................
                    <TextView
                        android:id="@+id/textView13"
                        android:paddingBottom="10dp"
                        android:paddingLeft="5dp"
                        android:paddingRight="5dp"
                        android:paddingTop="10dp"
                        android:text="@string/side_wo_colon"
                        android:textColor="@color/white"
                        android:textSize="16sp" />

                    <LinearLayout
                        android:layout_width="1dp"
                        android:layout_height="match_parent" >

                        <View style="@style/Divider" />
                    </LinearLayout>

                    <TextView
                        android:id="@+id/textView14"
                        android:paddingBottom="10dp"
                        android:paddingLeft="5dp"
                        android:paddingRight="5dp"
                        android:paddingTop="10dp"
                        android:text="@string/total"
                        android:textColor="@color/white"
                        android:textSize="16sp" />
                </TableRow>

                <!-- display this button in 3rd column via layout_column(zero based) -->

                <TableRow
                    android:id="@+id/tableRow2"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:background="#6F9C33" >

                    <TextView
                        android:id="@+id/textView21"
                        android:padding="5dp"
                        android:text="@string/servings"
                        android:textColor="@color/white"
                        android:textSize="16sp" />

                    <LinearLayout
                        android:layout_width="1dp"
                        android:layout_height="match_parent" >

                        <View style="@style/Divider" />
                    </LinearLayout>

    ..........
    .......
    ......
YasirAzgar
la source
0

Pour faire une ligne verticale, utilisez simplement un rectangle d'une largeur de 1dp:

<shape>
    <size
        android:width="1dp"
        android:height="16dp" />
    <solid
        android:color="#c8cdd2" />
</shape>

N'utilisez pas stroke, utilisez solid(qui est la couleur de "remplissage") pour spécifier la couleur de la ligne.

David Wasser
la source
-1
 <View
        android:layout_width="2dp"
        android:layout_height="40dp"

        android:background="#ffffff"
        android:padding="10dp" />`
Surender Kumar
la source