Course Android ouverte?

94

Est-il possible de créer un objet de forme Android avec un contour uniquement sur certains côtés?

Par exemple, j'ai:

<stroke 
 android:width="3dip" 
 android:color="#000000"
    android:dashWidth="10dip" 
    android:dashGap="6dip" />

Ce qui est similaire à ce CSS:

border: 3px dashed black;

Comment puis-je définir le trait d'un seul côté? Voici comment je le ferais en CSS:

border-left: 3px dashed black;

Comment faites-vous cela dans Android XML?

Reed Morse
la source

Réponses:

127

J'ai trouvé une bonne solution avec celle-ci:

<?xml version="1.0" encoding="utf-8"?>

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- This is the line -->
    <item android:top="-1dp" android:right="-1dp" android:left="-1dp">
      <shape>
            <solid android:color="@android:color/transparent" />
            <stroke android:width="1dp" android:color="#ffffff" />
      </shape>
    </item>

</layer-list>

Cela fonctionne bien au cas où vous auriez besoin d'un fond transparent mais toujours d'une couleur de trait ouverte (dans mon cas, je n'avais besoin que d'une ligne de fond). Si vous avez besoin d'une couleur d'arrière-plan, vous pouvez ajouter une couleur de forme unie comme dans la réponse Maragues.

MODIFIER 1

Parfois, pour les appareils à haute densité, l'utilisation de faibles valeurs de pendage peut se terminer par des courses ou des distances très minces ou invisibles. Cela peut également vous arriver lors de la définition des diviseurs ListView.

La solution de contournement la plus simple consiste à utiliser une distance de 1px au lieu de 1dp. Cela rendra la ligne toujours visible à toutes les densités. La meilleure solution serait de créer des ressources de dimension pour chaque densité, afin d'obtenir la meilleure taille pour chaque appareil.

Modifier 2

Amusant, mais j'ai essayé de l'utiliser 6 ans plus tard et je n'arrive pas à obtenir un bon résultat sur les appareils Lollipop.

La solution actuelle est probablement d'utiliser 9-patch. Android aurait dû apporter une solution simple à ce problème après tout ce temps.

htafoya
la source
Cela a également fonctionné pour moi, mais je ne sais pas exactement pourquoi j'ai dû utiliser -2dp au lieu de -1dp. Si j'utilisais ce dernier, je pourrais toujours voir une ligne mince.
Edu Zamora
1
@EduZamora oui, il semble que pour les appareils haute densité -1dp ne fonctionne pas comme prévu
htafoya
Je reçois également une bordure pour tous les côtés, mais pas uniquement une bordure inférieure.
Cheok Yan Cheng
@YanChengCHEOK essayez avec 1px au lieu de 1dp.
htafoya
@htafoya c'est une solution brillante. Merci!
abriggs
52

Je sais que cette question a été postée il y a longtemps, donc la réponse ne sera pas utilisée par la personne qui a posté cette question, mais cela peut quand même aider les autres.

 <?xml version="1.0" encoding="UTF-8"?>
    <!-- inset is used to remove border from top, it can remove border from any other side-->
    <inset xmlns:android="http://schemas.android.com/apk/res/android"
        android:insetTop="-2dp"
        >
    <shape xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/rectangle">
        <stroke android:width="1dp" android:color="#b7b7b7" />
        <corners android:bottomRightRadius="5dp"  android:bottomLeftRadius="5dp"/>

        <solid android:color="#454444"/>
    </shape>
    </inset>

Utilisez la insetbalise et attribuez une valeur négative à la bordure latérale que vous souhaitez supprimer.

Les valeurs possibles sont:

android:insetTop="-1dp" android:insetBottom="-1dp" android:insetLeft="-1dp" android:insetRight="-1dp"

Nirmal Dhara
la source
Ouais et ne faites pas ce que j'ai fait et essayez de mettre l'attribut inséré dans l'étiquette de trait sans lire le reste de la réponse! (merci pour la réponse BTW OP. Solution parfaite)
Kiran
élégant ! J'adore cette solution
Hao Qi
41

J'ai résolu cela en utilisant un calque de liste, combinant deux formes, dont l'une avec une hauteur de 1dp placée en bas

optionscreen_bottomrectangle.xml:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- This is the line -->
<item>
      <shape>
            <solid android:color="#535353" />
      </shape>
</item>
<!-- This is the main color -->
<item android:bottom="1dp">
     <shape>
           <solid android:color="#252525" />
     </shape>
</item>
</layer-list>

Ensuite, dans le fichier layout / main.xml

<TextView
    android:id="@+id/bottom_rectangle"
    android:background="@drawable/optionscreen_bottomrectangle"
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:layout_below="@id/table_options"
    android:layout_above="@id/exit_bar"/>

Ce qui remplit l'espace entre table_options et exit_bar avec un arrière-plan et juste avant que exit_bar imprime une ligne de 1dp. Cela a fait l'affaire pour moi, j'espère que cela aide quelqu'un d'autre.

Réponse modifiée pour placer les calques dans le bon ordre. Thx Alex!

Maragues
la source
Il peut être utile de ne pas publier de réponse si vous voulez vraiment avoir une réponse vous-même. Quand d'autres développeurs voient qu'il y a déjà une réponse (bien que dans ce cas ce soit en fait non), ils ne sont pas aussi enclins à répondre.
MrSnowflake
31

Une autre interprétation des autres réponses en utilisant plutôt le remplissage. Ce petit extrait fait une bordure en haut et en bas.

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- This is the line -->
    <item>
          <shape>
                <padding android:left="0dp" android:top="1dp" android:right="0dp" android:bottom="1dp"/>
                <solid android:color="#898989" />
          </shape>
    </item>
    <!-- This is the main color -->
    <item>
         <shape>
             <solid android:color="#ffffff" />
         </shape>
    </item>
</layer-list>
ug_
la source
4
C'est de loin la meilleure réponse si vous avez besoin de coins arrondis.
MacKinley Smith
Celui-ci m'a également énormément aidé. Veuillez essayer et voter pour
Garçon
@ug_ Je pense que c'est la meilleure approche. Fonctionne parfaitement, merci
Lalit Sharma
Travaux. Cela semble complètement faux dans le volet d'aperçu d'Android Studio (v1.1), mais sur l'appareil, tout va bien.
Murat Ögat
26

La réponse de @ Maragues est inversée, car les éléments dessinés de la liste des calques se dessinent de haut en bas (ce qui signifie que le dernier élément de la liste est dessiné en haut):

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- This is the line -->
<item>
      <shape>
            <solid android:color="#535353" />
      </shape>
</item>
<!-- This is the main color -->
<item android:bottom="1dp">
     <shape>
           <solid android:color="#252525" />
     </shape>
</item>

</layer-list>

Cela remplira efficacement la forme avec la couleur de la ligne, puis dessinera la couleur d'arrière-plan par-dessus, laissant le dernier 1dp clair pour que la couleur de la ligne apparaisse.

Alex Pretzlav
la source
2
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >


<item>
    <shape android:shape="rectangle" >
        <stroke  android:width="2dp"
                 android:color="#BBBBBB" />
        <solid android:color="@android:color/transparent" />
    </shape>
</item>
<item  android:bottom="2dp" >
    <shape android:shape="rectangle" >
        <stroke  android:width="2dp"
                 android:color="@color/main_background_color" />
        <solid android:color="@android:color/transparent" />
    </shape>
</item>

ensoleillé
la source
2

J'ai utilisé le code suivant.

<?xml version="1.0" encoding="UTF-8"?>
<!-- inset is used to remove border from top, it can remove border from any other side-->
<inset xmlns:android="http://schemas.android.com/apk/res/android"
    android:insetTop="-2dp" android:insetLeft="-2dp" android:insetRight="-2dp"
    >
    <shape xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/rectangle">
        <stroke android:width="1dp" android:color="@color/colorPrimary" />
        <solid android:color="#0000"/>
        <padding android:left="2dp" android:top="2dp" android:bottom="2dp" android:right="2dp"/>
    </shape>
</inset>
Ken W.
la source
0

Simple et efficace

Pour avoir une vue transparente et tout ce qui est à l'extérieur a une superposition d'une certaine couleur, ce que vous pouvez faire est de créer les vues qui encapsulent la vue centrale sans que les vues extérieures marchent sur la vue centrale .

De cette façon, vous évitez d'avoir un dessin externe à la mise en page et vous avez plus de contrôle sur les distances des vues sans avoir à effectuer des calculs à l'exécution.

<androidx.constraintlayout.widget.ConstraintLayout .. >

    <View
        android:id="@+id/center"
        android:layout_width="100dp"
        android:layout_height="100dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        android:background="@color/transparent"/>

   <View
        android:id="@+id/left_overlay"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@id/center"
        app:layout_constraintTop_toBottomOf="@id/top_overlay"
        app:layout_constraintBottom_toTopOf="@id/bottom_overlay"
        android:background="@color/black"
        android:alpha="0.5"
        />

    <View
        android:id="@+id/right_overlay"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintLeft_toRightOf="@id/center"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/top_overlay"
        app:layout_constraintBottom_toTopOf="@id/bottom_overlay"
        android:background="@color/black"
        android:alpha="0.5"
        />

    <View
        android:id="@+id/top_overlay"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toTopOf="@id/center"
        android:background="@color/black"
        android:alpha="0.5"
        />

    <View
        android:id="@+id/bottom_overlay"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@id/center"
        android:background="@color/black"
        android:alpha="0.5"
        />

</androidx.constraintlayout.widget.ConstraintLayout>

GL

Braian Coronel
la source