Tratto Android aperto?


93

È possibile creare un oggetto forma Android con tratto solo su alcuni lati?

Ad esempio, ho:

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

Che è simile a questo CSS:

border: 3px dashed black;

Come posso impostare la corsa su un solo lato? Ecco come lo farei in CSS:

border-left: 3px dashed black;

Come si esegue questa operazione in XML Android?

Risposte:


126

Ho ottenuto una buona soluzione con questo:

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

Funziona bene nel caso in cui sia necessario uno sfondo trasparente ma ancora un colore del tratto aperto (nel mio caso avevo solo bisogno di una linea di fondo). Se hai bisogno di un colore di sfondo, puoi aggiungere un colore di forma solida come nella risposta di Maragues.

MODIFICA 1

A volte, per i dispositivi ad alta densità, l'utilizzo di valori di immersione bassi può portare a tratti o distanze molto sottili o invisibili. Questo può accadere anche quando si impostano i divisori ListView.

La soluzione più semplice consiste nell'utilizzare una distanza di 1px invece di 1dp. Ciò renderà la linea sempre visibile a tutte le densità. La soluzione migliore sarebbe creare risorse dimensionali per ogni densità, per ottenere la dimensione migliore per ogni dispositivo.

Modifica 2

Divertente, ma ho provato a usarlo 6 anni dopo e non riesco ad ottenere un buon risultato sui dispositivi Lollipop.

Probabilmente la soluzione attuale è usare 9 patch. Android avrebbe dovuto trovare una soluzione semplice per questo problema dopo tutto questo tempo.


Questo ha funzionato anche per me, ma non so esattamente perché ho dovuto usare -2dp invece di -1dp. Se avessi usato quest'ultimo, potrei ancora vedere una linea sottile.
Edu Zamora

1
@EduZamora sì, sembra che per i dispositivi ad alta densità -1dp non funzioni come previsto
htafoya

Ricevo anche il bordo per tutti i lati, ma non solo il bordo inferiore.
Cheok Yan Cheng

@YanChengCHEOK prova con 1px invece di 1dp.
htafoya

@htafoya questa è una soluzione brillante. Grazie!
abriggs

52

So che questa domanda è stata pubblicata molto tempo fa, quindi la risposta non verrà utilizzata dalla persona che ha pubblicato questa domanda, ma potrebbe comunque aiutare gli altri.

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

Usa il insettag e assegna un valore negativo al bordo laterale che desideri rimuovere.

I valori possibili sono:

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


Sì, e non fare quello che ho fatto e prova a inserire il riquadro attr nel tag del tratto senza leggere il resto della risposta! (grazie per la risposta BTW OP. Soluzione perfetta)
Kiran

elegante! Adoro questa soluzione
Hao Qi

41

Ho risolto il problema utilizzando un list-layer, combinando due forme, una delle quali con altezza 1dp posta in basso

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>

Quindi, nel file 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"/>

Che riempie il divario tra table_options e exit_bar con uno sfondo e appena prima di exit_bar stampa una riga 1dp. Questo ha funzionato per me, spero che aiuti qualcun altro.

Risposta modificata per posizionare i livelli nell'ordine corretto. Grazie Alex!


Potrebbe essere utile non pubblicare una risposta se vuoi davvero avere una risposta da solo. Quando altri sviluppatori vedono che c'è già una risposta (anche se in questo caso è in realtà no) non sono così inclini a rispondere.
MrSnowflake

31

Un'altra interpretazione delle altre risposte usando invece il padding. Questo piccolo frammento fa un bordo in alto e in basso.

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

4
Questa è di gran lunga la risposta migliore se hai bisogno di angoli arrotondati.
MacKinley Smith

Anche questo mi ha aiutato moltissimo. Per favore, provalo e vota a favore
Ragazzo

@ug_ Penso che questo sia l'approccio migliore. Funziona perfettamente, grazie
Lalit Sharma

Lavori. Sembra completamente sbagliato nel riquadro di anteprima di Android Studio (v1.1) ma sul dispositivo va bene.
Murat Ögat

26

La risposta di @ Maragues è al contrario, poiché gli elementi disegnabili dell'elenco dei livelli disegnano dall'alto verso il basso (il che significa che l'ultimo elemento nell'elenco è disegnato in alto):

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

Questo riempirà efficacemente la forma con il colore della linea, quindi disegna il colore di sfondo sopra di essa, lasciando l'ultimo 1dp chiaro per far trasparire il colore della linea.


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>


2

Ho usato il seguente codice.

<?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>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.