Wie zeichne ich einen Rand auf nur einer Seite eines linearen Layouts?

185

Ich kann einen Rahmen für ein lineares Layout zeichnen, aber er wird von allen Seiten gezeichnet. Ich möchte es nur auf die rechte Seite beschränken, wie Sie es in CSS tun (Rand rechts: 1px durchgehend rot;).

Ich habe es versucht, aber es zieht immer noch nach allen Seiten:

<?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:height="2dp"
            android:width="2dp"
            android:color="#FF0000" />

        <solid android:color="#000000" />

        <padding
            android:bottom="0dp"
            android:left="0dp"
            android:right="1dp"
            android:top="0dp" />

        <corners
            android:bottomLeftRadius="0dp"
            android:bottomRightRadius="5dp"
            android:radius="1dp"
            android:topLeftRadius="5dp"
            android:topRightRadius="0dp" />
    </shape>
</item>

Irgendwelche Vorschläge, wie dies erreicht werden kann?

Übrigens möchte ich nicht den Hack verwenden, eine Ansicht mit einer Breite von 1 dp auf die erforderliche Seite zu setzen.

Nitin Bansal
quelle
Sie können drawableLeft in Ihrem Layout verwenden
njzk2

Antworten:

358

Sie können dies verwenden, um den Rand auf einer Seite zu erhalten

<?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="#FF0000" />
    </shape>
</item>
<item android:left="5dp">
    <shape android:shape="rectangle">
        <solid android:color="#000000" />
    </shape>
</item>
</layer-list>

BEARBEITET

Da viele, einschließlich mir, einen einseitigen Rand mit transparentem Hintergrund haben wollten, habe ich einen implementiert BorderDrawable, der mir Ränder mit unterschiedlicher Größe und Farbe auf die gleiche Weise geben kann, wie wir CSS verwenden. Dies konnte jedoch nicht über XML verwendet werden. Zur Unterstützung von XML habe ich eine hinzugefügt, BorderFrameLayoutin die Ihr Layout eingeschlossen werden kann.

Die vollständige Quelle finden Sie in meinem Github .

Vivek Khandelwal
quelle
5
Was ist, wenn Sie eine feste Farbe auf Alpha-Basis mit einem unteren Rand wünschen? Ich habe über eine Lösung mit der Android Drawable XML-API nachgedacht, aber ich kann es nicht herausfinden.
Mario Lenci
Dies funktionierte bei mir nicht - seltsamerweise war das Gegenteil von dem, was ich wollte, eine dunklere Farbe auf der Innenseite, mit dem grauen Farbverlauf, den ich für die Boarder überlagerte. Ich habe darüber nachgedacht, ein Rechteck in einer bestimmten Größe zeichnbar zu machen, um es als zeichnbares Links auf das Objekt zu setzen. Dies scheint nicht so rationalisiert zu sein.
Jbenowitz
@jbenowitz: Die Reihenfolge des Elements in der Ebenenliste ist wichtiger. Wenn Sie umkehren, erhalten Sie das Ergebnis.
Vivek Khandelwal
Ich habe dies behoben, indem ich einen Strich der Randfarbe und der Form hinzugefügt habe, die die Tastenfarbe bleibt. Das hat funktioniert.
Jbenowitz
242

Einfach wie ein Kuchen und ermöglicht ein transparentes BG:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <gradient
        android:angle="0"
        android:startColor="#f00"
        android:centerColor="@android:color/transparent"
        android:centerX="0.01" />
</shape>

Ändern Sie den Winkel, um die Randposition zu ändern:

  • 0 = links
  • 90 = unten
  • 180 = richtig
  • 270 = oben
Oded Breiner
quelle
19
Dies ist bei weitem die beste Antwort hier, schade, dass es nicht positiv bewertet wird
mittelmania
11
Schön, aber ich würde es sicherlich nicht als "einfach wie Kuchen" beschreiben.
Funkybro
7
Dies funktioniert nicht, wenn Sie einen dickeren Rand benötigen oder wenn Sie Ränder auf mehreren Seiten benötigen.
Holographisches Prinzip
1
@codeman - Verwenden Sie dies als Hintergrund für Ihre Ansicht, dann erbt es seine Höhe.
Oded Breiner
2
Wie stelle ich den Strich oder die Randbreite ein?
Ruturaj Patil
101

Es ist auch möglich, das, was Sie wollen, mit einer einzigen Ebene zu implementieren

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

    <item
        android:bottom="-5dp"
        android:right="-5dp"
        android:top="-5dp">
        <shape android:shape="rectangle" >
            <solid android:color="@color/color_of_the_background" />

            <stroke
                android:width="5dp"
                android:color="@color/color_of_the_border" />
        </shape>
    </item>

</layer-list>

auf diese Weise nur linke Rand ist sichtbar , aber Sie eine beliebige Kombination Sie mit durch das Spielen erreichen können bottom, left, rightund topAttribute des itemElements

Viktor Grekov
quelle
3
Dies ist auf jeden Fall nützlich, wenn Sie eine andere Hintergrundfarbe haben und dieses zeichnbare Hintergrundbild mit einem Rand überlagern möchten. (y)
Aung Pyae
3
Genau das, was ich brauche, aber ist es richtig, negative Polster zu verwenden?
IlyaEremin
1
Dies ist die beste Lösung. Ich störe, was -5dp dort macht.
Amit Kumar
1
Negatives Auffüllen ist in HTML / CSS üblich. Es treibt die Dinge einfach in die andere Richtung. Nach meiner Erfahrung scheint es auch in Android vollkommen gültig zu sein.
Spaaarky21
Implementierungen mit negativen Rändern funktionieren nicht gut, wenn Ihr Layout clipChildren = false oder clipToPadding = false enthält. Wenn dies der Fall ist, können Sie die Lösung mit zwei überlappenden Rechtecken verwenden, wie von Vivek Khandelwal
Jesús Barrera
79

Um einen Rand auf nur einer Seite eines Zeichens zu erhalten, wenden Sie ein Negativ insetauf die anderen 3 Seiten an (wodurch diese Ränder außerhalb des Bildschirms gezeichnet werden).

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

    <shape android:shape="rectangle">
        <stroke android:width="2dp" android:color="#FF0000" />
        <solid android:color="#000000" />
    </shape>

</inset>

Geben Sie hier die Bildbeschreibung ein

Dieser Ansatz ähnelt der Antwort von Naykah, jedoch ohne die Verwendung von a layer-list.

Soldat
quelle
4
Dies ist die beste Antwort IMO
James
Sehr gute Antwort, ich muss nur die Breite und den Einschub auf 10dp ändern :) Und außerdem brauche ich einen Rand auf der linken Seite, also ändere ich android: insetLeft in android: insetRight. So einfach! Klicken Sie auf die Schaltfläche Material behalten: D
Phuong
Genau das, was ich brauchte, ändern Sie insertXoben, um zu entscheiden, welche Grenzen angezeigt werden sollen und welche nicht.
CularBytes
Ich kann sogar eine Volltonfarbe von @null haben und dann verursacht diese Methode kein Überziehen. Genius. Danke dir!
Unbekannt
2
Achtung: Dadurch wird der Inhalt Ihrer Ansicht verschoben und die Größe geändert. Vorsichtig verwenden.
Vovahost
7

Alternativ (wenn Sie keinen Hintergrund verwenden möchten) können Sie dies einfach tun, indem Sie eine Ansicht wie folgt erstellen:

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

Wenn Sie nur einen rechten Rand haben möchten, platzieren Sie diesen nach dem Layout (wo Sie den Rand haben möchten):

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

Wenn Sie nur einen linken Rand haben möchten, platzieren Sie diesen vor dem Layout (wo Sie den Rand haben möchten):

Hat für mich gearbeitet ... Ich hoffe, es hilft mir ...

Nishant Jha
quelle
6

Ich konnte den Effekt mit dem folgenden Code erzielen

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

Sie können Ihre Anforderungen an die Randposition anpassen, indem Sie die Verschiebungsrichtung ändern

IvelinStanchev
quelle
5
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" >
        <shape>
            <solid
                android:color="#f28b24" />
            <stroke
                android:width="1dp"
                android:color="#f28b24" />
            <corners
                android:radius="0dp"/>
            <padding
                android:left="0dp"
                android:top="0dp"
                android:right="0dp"
                android:bottom="0dp" />
        </shape>
    </item>
    <item>
        <shape>
            <gradient
                android:startColor="#f28b24"
                android:endColor="#f28b24"
                android:angle="270" />
            <stroke
                android:width="0dp"
                android:color="#f28b24" />
            <corners
                android:bottomLeftRadius="8dp"
                android:bottomRightRadius="0dp"
                android:topLeftRadius="0dp"
                android:topRightRadius="0dp"/>
            <padding
                android:left="10dp"
                android:top="10dp"
                android:right="10dp"
                android:bottom="10dp" />
        </shape>
    </item>
</selector>
Alejandrocordon
quelle
4

Ein weiteres gutes Beispiel Beispiel

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<inset xmlns:android="http://schemas.android.com/apk/res/android"
     android:insetRight="-2dp">

     <shape android:shape="rectangle">
         <corners
             android:bottomLeftRadius="4dp"
             android:bottomRightRadius="0dp"
             android:topLeftRadius="4dp"
             android:topRightRadius="0dp" />
         <stroke
             android:width="1dp"
             android:color="@color/nasty_green" />
         <solid android:color="@android:color/transparent" />
     </shape>

</inset>
Muklas
quelle
2

Es gibt keine Erwähnung über neun-Patch - Dateien hier. Ja, Sie müssen die Datei erstellen, aber es ist ziemlich einfach und es ist wirklich eine Lösung, die " Cross-Version und Transparenz unterstützt ". Wenn die Datei in das drawable-nodpiVerzeichnis gestellt wird, funktioniert sie pxbasierend und drawable-mdpifunktioniert ungefähr als dp-Basis (dank Resample).

Beispieldatei für die ursprüngliche Frage ( Rand rechts: 1px durchgehend rot; ) ist hier:

http://ge.tt/517ZIFC2/v/3?c

Legen Sie es einfach in das drawable-nodpiVerzeichnis.

Quark
quelle
1

Ränder in verschiedenen Farben. Ich habe 3 Artikel verwendet.

<?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/colorAccent" />
        </shape>
    </item>
    <item android:top="3dp">
        <shape android:shape="rectangle">
            <solid android:color="@color/light_grey" />
        </shape>
    </item>
    <item
        android:bottom="1dp"
        android:left="1dp"
        android:right="1dp"
        android:top="3dp">
        <shape android:shape="rectangle">
            <solid android:color="@color/colorPrimary" />
        </shape>
    </item>
</layer-list>
Ritesh
quelle