Jak narysować granicę tylko z jednej strony liniowego układu?

186

Jestem w stanie narysować granicę do układu liniowego, ale rysuje się ze wszystkich stron. Chcę ograniczyć to tylko do prawej strony, tak jak w CSS (border-right: 1px solid red;).

Próbowałem tego, ale nadal rysuje się ze wszystkich stron:

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

Wszelkie sugestie, jak to osiągnąć?

BTW, nie chcę korzystać z włamania polegającego na umieszczeniu widoku o szerokości 1dp na wymaganej stronie.

Nitin Bansal
źródło
możesz użyć drawableLeft w swoim układzie
njzk2

Odpowiedzi:

359

Możesz użyć tego, aby uzyskać granicę po jednej stronie

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

EDYTOWANE

Ponieważ wielu włącznie ze mną chciało mieć jednostronną ramkę z przezroczystym tłem, wdrożyłem taką, BorderDrawablektóra mogłaby dać mi ramki o innym rozmiarze i kolorze w taki sam sposób, jak używamy css. Ale nie można tego użyć przez xml. Do obsługi XML dodałem plik, BorderFrameLayoutw którym można zawinąć twój układ.

Zobacz mój github, aby uzyskać pełne źródło.

Vivek Khandelwal
źródło
5
co jeśli chcesz mieć jednolity kolor oparty na alfa z dolną ramką? Zastanawiałem się nad rozwiązaniem tego problemu za pomocą interfejsu API XML Drawable dla Androida, ale nie mogę tego rozgryźć.
Mario Lenci
Nie działało to dla mnie - dziwnie zrobiło się odwrotność tego, co chciałem, ciemniejszego koloru w środku, z szarym gradientem, który nałożyłem na granice. Zastanawiałem się nad utworzeniem prostokąta do rysowania w określonym rozmiarze, aby umieścić go jako element do przeciągnięcia w lewo na przedmiocie. To nie wydaje się tak usprawnione.
jbenowitz
@jbenowitz: Kolejność elementów na liście warstw jest ważniejsza. Jeśli odwrócisz, otrzymasz ten wynik.
Vivek Khandelwal
Naprawiłem to, dodając obrys koloru obramowania i kształtu pozostającego kolorem przycisku. To załatwiło sprawę.
jbenowitz
242

Łatwe jak ciasto, pozwalając na przezroczyste 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>

Zmień kąt, aby zmienić położenie granicy:

  • 0 = pozostało
  • 90 = dno
  • 180 = prawo
  • 270 = góra
Oded Breiner
źródło
19
To zdecydowanie najlepsza odpowiedź tutaj, szkoda, że ​​nie jest oceniana
mittelmania
11
Fajnie, ale z pewnością nie opisałbym tego jako „łatwe jak ciasto”.
funkybro
7
Nie działa to, jeśli potrzebujesz grubszej ramki lub jeśli potrzebujesz ramek z wielu stron.
holograficzna zasada
1
@codeman - użyj tego jako tła do swojego widoku, a następnie odziedziczy jego wysokość.
Oded Breiner
2
jak wyregulować szerokość obrysu lub obramowania?
Ruturaj Patil
101

możliwe jest również zaimplementowanie tego, co chcesz, za pomocą pojedynczej warstwy

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

W ten sposób tylko lewa granica jest widoczna, ale można osiągnąć dowolną kombinację chcesz grając z bottom, left, righti topatrybuty w itemelemencie

Viktor Grekov
źródło
3
Jest to zdecydowanie przydatne, gdy masz inny kolor tła i chcesz nałożyć tę rysowaną bg z ramką. (y)
Aung Pyae,
3
Dokładnie to, czego potrzebuję, ale czy właściwe jest stosowanie ujemnych wypełnień?
IlyaEremin
1
To najlepsze rozwiązanie. Niepokoi mnie to, co robi -5dp.
Amit Kumar
1
Wypełnianie ujemne jest powszechne w HTML / CSS. Po prostu popycha rzeczy w innym kierunku. Z mojego doświadczenia wynika, że ​​wydaje się również całkowicie poprawny w Androidzie.
spaaarky21
Implementacje używające marginesów ujemnych nie działają dobrze, jeśli układ ma clipChildren = false lub clipToPadding = false. W takim przypadku możesz użyć rozwiązania z dwoma nakładającymi się prostokątami, jak zaproponował Vivek Khandelwal
Jesús Barrera
80

Aby uzyskać ramkę tylko z jednej strony rysowalnego, nałóż negatyw insetna pozostałe 3 strony (powodując, że te granice zostaną narysowane poza ekranem).

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

wprowadź opis zdjęcia tutaj

To podejście jest podobne do odpowiedzi naykah, ale bez użycia layer-list.

policjant
źródło
4
To najlepsza odpowiedź IMO
James
bardzo dobra odpowiedź, po prostu muszę zmienić szerokość i wstawić na 10dp :) I więcej, potrzebuję ramki po lewej stronie, więc zmieniam android: insetLeft na android: insetRight. Tak prosty! Kliknij przycisk Keeping Material: D
Phuong,
Dokładnie to, czego potrzebowałem, zmień insertXu góry, aby zdecydować, które granice pokazać, a co nie.
CularBytes
Mogę nawet mieć jednolity kolor @ null, a następnie ta metoda nie powoduje przerysowania. Geniusz. Dziękuję Ci!
Unknownweirdo
2
Uwaga: spowoduje to przesunięcie zawartości twojego widoku i zmianę jego rozmiaru. Używaj ostrożnie.
vovahost
7

Alternatywnie (jeśli nie chcesz używać tła), możesz to łatwo zrobić, tworząc następujący widok:

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

Aby mieć tylko prawą ramkę, umieść ją za układem (tam, gdzie chcesz mieć ramkę):

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

Aby mieć tylko lewą ramkę, umieść ją przed układem (tam, gdzie chcesz mieć ramkę):

Pracował dla mnie ... Mam nadzieję, że to pomoże ...

Nishant Jha
źródło
6

Byłem w stanie osiągnąć efekt za pomocą następującego kodu

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

Możesz dostosować się do swoich potrzeb w zakresie położenia granicznego, zmieniając kierunek przemieszczenia

IvelinStanchev
źródło
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
źródło
5

Kolejny świetny przykład przykład

<?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
źródło
2

Nie ma tu mowy o plikach z dziewięcioma łatami . Tak, musisz utworzyć plik, jednak jest to dość łatwa robota i jest to naprawdę rozwiązanie „ obsługujące wiele wersji i obsługujące przezroczystość ”. Jeśli plik zostanie umieszczony w drawable-nodpikatalogu, działa w pxoparciu, a drawable-mdpidziała w przybliżeniu jako baza dp (dzięki resample).

Przykładowy plik oryginalnego pytania ( obramowanie z prawej strony: 1px ciągłe czerwone; ) znajduje się tutaj:

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

Po prostu umieść go w drawable-nodpikatalogu.

twaróg
źródło
2

Granice różnych kolorów. Użyłem 3 przedmiotów.

<?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>
Rytuał
źródło