Dzięki temu osiągnąłem dobre rozwiązanie:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<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>
Działa to dobrze, jeśli potrzebujesz przezroczystego tła, ale wciąż otwartego koloru obrysu (w moim przypadku potrzebowałem tylko dolnej linii). Jeśli potrzebujesz koloru tła, możesz dodać jednolity kolor kształtu, jak w odpowiedzi Maragues.
EDYCJA 1
Czasami, w przypadku urządzeń o wysokiej gęstości, używanie niskich wartości spadku może kończyć się bardzo cienkimi lub niewidocznymi pociągnięciami lub odległościami. Może się to zdarzyć również podczas ustawiania dzielników ListView.
Najprostszym obejściem jest użycie odległości 1 piksela zamiast 1 dp. Dzięki temu linia będzie zawsze widoczna przy wszystkich gęstościach. Najlepszym rozwiązaniem byłoby utworzenie zasobów wymiarów dla każdej gęstości, aby uzyskać najlepszy rozmiar dla każdego urządzenia.
Edytuj 2
Zabawne, ale próbowałem tego użyć 6 lat później i nie mogę uzyskać dobrego wyniku na urządzeniach Lollipop.
Prawdopodobnie obecnym rozwiązaniem jest użycie 9 łatek. Android po tylu latach powinien był łatwo rozwiązać ten problem.
Wiem, że to pytanie zostało wysłane dawno temu, więc odpowiedź nie zostanie użyta przez osobę, która je opublikowała, ale może pomóc innym.
<?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>
Użyj
inset
tagu i podaj ujemną wartość krawędzi bocznej, którą chcesz usunąć.Możliwe wartości to:
android:insetTop="-1dp" android:insetBottom="-1dp" android:insetLeft="-1dp" android:insetRight="-1dp"
źródło
Rozwiązałem to używając warstwy listy, łączącej dwa kształty, z których jeden o wysokości 1dp umieszczony na dole
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>
Następnie w pliku 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"/>
Wypełnia lukę między table_options i exit_bar tłem, a tuż przed exit_bar drukuje linię 1dp. To załatwiło sprawę dla mnie, mam nadzieję, że pomoże to komuś innemu.
Odpowiedź została zmieniona w celu umieszczenia warstw we właściwej kolejności. Dzięki Alex!
źródło
Kolejne podejście do innych odpowiedzi wykorzystujących zamiast tego dopełnienie. Ten mały skrawek tworzy granicę na górze i na dole.
<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>
źródło
Odpowiedź @ Maragues jest odwrotna, ponieważ rysunki na liście warstw rysują się od góry do dołu (co oznacza, że ostatni element na liście jest rysowany na górze):
<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>
Spowoduje to efektywne wypełnienie kształtu kolorem linii, a następnie narysowanie na nim koloru tła, pozostawiając ostatnie 1 dp przezroczyste, aby kolor linii był widoczny.
źródło
<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>
źródło
Użyłem następującego kodu.
<?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>
źródło
Proste i wydajne
Aby mieć przejrzysty widok i wszystko, co jest na zewnątrz, ma nakładkę w jakimś kolorze, możesz stworzyć widoki, które obejmują widok środkowy, bez wkraczania widoków zewnętrznych na widok środkowy .
W ten sposób unikniesz konieczności rysowania zewnętrznego układu i masz większą kontrolę nad odległościami widoków bez konieczności wykonywania obliczeń w czasie wykonywania.
<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
źródło