Android LinearLayout: Dodaj obramowanie z cieniem wokół LinearLayout

147

Chciałbym utworzyć takie same obramowanie tego LinearLayout, jak w przykładzie:

wprowadź opis obrazu tutaj

W tym przykładzie widzimy, że obramowanie nie jest takie samo na całym linearLayout. Jak mogę to utworzyć za pomocą pliku XML do rysowania?

Na razie udało mi się utworzyć prostą ramkę wokół LinearLayout w następujący sposób:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
  <corners
      android:radius="1dp"
      android:topRightRadius="0dp"
      android:bottomRightRadius="0dp"
      android:bottomLeftRadius="0dp" />
  <stroke
      android:width="1dp"
      android:color="#E3E3E1" />

  <solid android:color="@color/blanc" />

</shape>
wawanopoulos
źródło
1
możesz użyć backgrounddo tego właściwości ... utwórz jeden plik XML z kształtem takim jak prostokąt, kolor i efekt cienia i ustaw go jako tło dla swojego układu liniowego ..
Pragnesh Ghoda シ
użyj obrysu dla szarej ramki i efektu wypełnienia
Pragnesh Ghoda シ
Myślę, że jego dwa układy xml, powiedzmy, że jeden to układ liniowy, a wewnętrzny to układ względny z wypełnieniem
Giru Bhai
@ Prag's Czy mógłbyś mi pomóc przy tworzeniu tego pliku xml?
wawanopoulos
1
Alternatywnym sposobem może być użycie obrazu 9 łatek jako tła dla twojego układu. Pozwoliłoby to na naprawdę gładki, blaknący cień (moim zdaniem bardzo realistyczny).
Phantômaxx,

Odpowiedzi:

257

Spróbuj tego..

<?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="#CABBBBBB"/>
            <corners android:radius="2dp" />
        </shape>
    </item>

    <item
        android:left="0dp"
        android:right="0dp"
        android:top="0dp"
        android:bottom="2dp">
        <shape android:shape="rectangle">
            <solid android:color="@android:color/white"/>
            <corners android:radius="2dp" />
        </shape>
    </item>
</layer-list>
Hariharan
źródło
@Hariharan Wielkie dzięki! Wypróbowałem twój kod i wygląda na to, że jest w porządku. Ale jest jeszcze jedna rzecz do zrobienia, jak mogę dodać cienką ramkę (1 dp) po lewej i prawej stronie układu liniowego? (jako przykład)
wawanopoulos
2
@wawanopoulos Wystarczy wymienić "0dp"z "1dp"odpowiadając Hariharan użytkownika.
Phantômaxx
możesz dodać kolor #EAEAEA do układu nadrzędnego, aby wyglądał jak obraz pytania
Samad
3
Sugerowałbym również, abyś mógł użyć <gradient>w swoim, <shape>aby wzmocnić efekt obramowania, a także, jeśli jest to naprawdę efekt, którego potrzebuje twój interfejs użytkownika, zamiast tylko obramowania w jednolitym kolorze.
patrickjason91
upewnij się, że masz układ wewnętrzny z parametrem match_parent, a następnie podaj margines 1 układowi wewnętrznemu
Shaktisinh Jadeja
82

Dlatego istnieje CardView. CardView | Programiści Androida
To tylko FrameLayout, który obsługuje podniesienie uprawnień w urządzeniach typu pre-Lollipop.

<android.support.v7.widget.CardView
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:cardUseCompatPadding="true"
    app:cardElevation="4dp"
    app:cardCornerRadius="3dp" >

    <!-- put whatever you want -->

</android.support.v7.widget.CardView>

Aby z tego skorzystać, musisz dodać zależność do build.gradle:

compile 'com.android.support:cardview-v7:23.+'
Ray Suhyun Lee
źródło
jak zmienić kolor cienia
Aditay Kaushal
shadow jest bardzo słaby stackoverflow.com/questions/49076188/ ...
user924
1
bardzo dziwne zachowanie na urządzeniach z 4.4.4 (lub podobnym). Do widoku kart dodawany jest ogromny margines, co sprawia, że ​​interfejs użytkownika jest bardzo brzydki.
Morteza Rastgoo
To powinna być akceptowana odpowiedź. Jedna mała aktualizacja. Powinieneś użyć androidx one -> androidx.cardview.widget.CardView
bogdan
59

Najlepsze rezultaty osiągam, używając grafiki z 9 patchami.

Możesz po prostu utworzyć indywidualną grafikę 9 łatek za pomocą następującego edytora: http://inloop.github.io/shadow4android/

Przykład:

Grafika z 9 patchami:

Grafika z 9 patchami:

Wynik:

wprowadź opis obrazu tutaj

Źródło:

<LinearLayout
android:layout_width="200dp"
android:layout_height="200dp"
android:orientation="vertical"
android:background="@drawable/my_nine_patch"
funcoder
źródło
1
Jak mogę ukryć czarną linię? Proszę o pomoc
Isaac Darlong
@Isaac zapisz obraz jako my_nine_patch.9.png (.9.png to 9 wsadowy obraz)
arun
TO JEST NAJLEPSZY!
Numanqmr
35

okej, wiem, że to już za późno. ale miałem te same wymagania. rozwiązałem w ten sposób

1. Najpierw utwórz plik xml (przykład: border_shadow.xml) w folderze „drawable” i skopiuj do niego poniższy kod.

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

<item>
    <shape>
        <!-- set the shadow color here -->
        <stroke
            android:width="2dp"
            android:color="#7000" />

        <!-- setting the thickness of shadow (positive value will give shadow on that side) -->

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

        <corners android:radius="3dp" />
    </shape>
</item>

<!-- Background -->

<item>
    <shape>
        <solid android:color="#fff" />
        <corners android:radius="3dp" />
    </shape>
</item>

2. teraz na układzie, w którym chcesz cień (przykład: LinearLayout), dodaj to w android: background

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_margin="8dip"
    android:background="@drawable/border_shadow"
    android:orientation="vertical">

i to działało dla mnie.

user3619170
źródło
20

To takie proste:

Utwórz plik do rysowania z gradientem takim jak ten:

dla cienia pod widokiem below_shadow.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">   
<gradient
    android:startColor="#20000000"
    android:endColor="@android:color/transparent"
    android:angle="270" >
</gradient>
</shape>

dla cienia nad widokiem above_shadow.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">   
<gradient
    android:startColor="#20000000"
    android:endColor="@android:color/transparent"
    android:angle="90" >
</gradient>
</shape>

i tak dalej dla prawego i lewego cienia po prostu zmień kąt gradientu :)

Morteza Rastgoo
źródło
gdzie nazywam below_shadow? tło widoku?
Arthur Melo
1
Utwórz plik XML below_shadow, a następnie w swoim widoku dodaj „Widok” do układu i ustaw below_shadow.xml jako tło tego widoku
Morteza Rastgoo
Zrobiłem to samo, co powiedziałeś, ale moje „above_shadow” nie jest przezroczyste, kiedy umieszczam ten widok w widoku niestandardowym. Działa dobrze osobno. Co powinienem zrobić?
SoYoung,
18

Alternatywnie możesz użyć obrazu z 9 wstawkami jako tła dla swojego układu, co pozwoli na bardziej „naturalne” cienie:

wprowadź opis obrazu tutaj

Wynik:

wprowadź opis obrazu tutaj

Umieść obraz w swoim /res/drawablefolderze.
Upewnij się, że rozszerzenie pliku to .9.png, a nie.png

Nawiasem mówiąc, jest to zmodyfikowany (zmniejszony do minimalnego rozmiaru kwadratowego) istniejący zasób znaleziony w folderze zasobów SDK API 19.
Zostawiłem czerwone znaczniki, ponieważ nie wydają się być szkodliwe, jak pokazano w narzędziu draw9patch.

[EDYTOWAĆ]

Około 9 łatek, na wypadek gdybyś nigdy nie miał z nimi nic wspólnego.

Po prostu dodaj go jako tło swojego widoku.

Obszary zaznaczone na czarno (lewy i górny) rozciągną się (pionowo, poziomo).
Obszary zaznaczone na czarno (prawy, dolny) definiują „obszar zawartości” (gdzie można dodać tekst lub widoki - jeśli chcesz, możesz nazwać nieoznaczone regiony „dopełnieniem”).

Samouczek: http://radleymarx.com/blog/simple-guide-to-9-patch/

Phantômaxx
źródło
1
Po prostu dodaj go jako tło swojego widoku. Obszary zaznaczone na czarno (lewy i górny) rozciągną się (pionowo, poziomo). Obszary zaznaczone na czarno (prawy, dolny) definiują „obszar treści” (gdzie można dodać tekst lub widoki - nazwij to „dopełnieniem”, jeśli chcesz). Samouczek: radleymarx.com/blog/simple-guide-to-9-patch
Phantômaxx
9

Tworzysz plik .xml w drawable o nazwie drop_shadow.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!--<item android:state_pressed="true">
        <layer-list>
            <item android:left="4dp" android:top="4dp">
                <shape>
                    <solid android:color="#35000000" />
                    <corners android:radius="2dp"/>
                </shape>
            </item>
            ...
        </layer-list>
    </item>-->
    <item>
        <layer-list>
            <!-- SHADOW LAYER -->
            <!--<item android:top="4dp" android:left="4dp">
                <shape>
                    <solid android:color="#35000000" />
                    <corners android:radius="2dp" />
                </shape>
            </item>-->
            <!-- SHADOW LAYER -->
            <item>
                <shape>
                    <solid android:color="#35000000" />
                    <corners android:radius="2dp" />
                </shape>
            </item>
            <!-- CONTENT LAYER -->
            <item android:bottom="3dp" android:left="1dp" android:right="3dp" android:top="1dp">
                <shape>
                    <solid android:color="#ffffff" />
                    <corners android:radius="1dp" />
                </shape>
            </item>
        </layer-list>
    </item>
</selector>

Następnie:

<LinearLayout
...
android:background="@drawable/drop_shadow"/>
Anh Duy
źródło
3

Użyj tej pojedynczej linii i miej nadzieję, że osiągniesz najlepszy wynik;

zastosowanie: android:elevation="3dp" Dostosuj rozmiar tak bardzo, jak potrzebujesz, i jest to najlepszy i najprostszy sposób na uzyskanie cieni, takich jak przyciski i inne domyślne cienie Androida. Daj mi znać, czy zadziałało!

Tamim
źródło
@ MichałZiobro Używaj go ze swoimi układami, tak jakbyś miał układ nad innym, który jest mniejszy i chcesz pokazać cień. powinno działać. Może się okazać, że Twoje teksty i przyciski staną się niewidoczne, ale kiedy uruchomisz aplikację, zobaczysz najlepszy cień. Nie jestem pewien, czy to jakiś błąd czy coś, ale w moim przypadku, gdy używam tego kodu, wszystkie moje widoki są niewidoczne w podglądzie AS, ale działa najlepiej w aplikacji, gdy debuguję / uruchamiam ją na moim urządzeniu. Daj mi znać, czy zadziałało, czy nie. Dzięki.
Tamim
3

Jeśli masz już obramowanie z kształtu, po prostu dodaj wysokość:

<LinearLayout
    android:id="@+id/layout"
    ...
    android:elevation="2dp"
    android:background="@drawable/rectangle" />
Krzynool
źródło
2
Jakie jest zachowanie na API <21?
CoolMind
1
Niestety nie działa przed Lollipopem, więc powinieneś użyć innych odpowiedzi na to pytanie. Ale jeśli celujesz w nowsze telefony, jest to dość łatwy sposób, który działa dobrze.
Krzynool
2

1. Najpierw utwórz plik XML o nazwie shadow.xml w folderze „drawable” i skopiuj do niego poniższy kod.

 <?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="#CABBBBBB" />
                <corners android:radius="10dp" />
            </shape>
        </item>

        <item
            android:bottom="6dp"
            android:left="0dp"
            android:right="6dp"
            android:top="0dp">
            <shape android:shape="rectangle">
                <solid android:color="@android:color/white" />
                <corners android:radius="4dp" />
            </shape>
        </item>
    </layer-list>

Następnie dodaj listę warstw jako tło w swoim LinearLayout.

<LinearLayout
        android:id="@+id/header_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/shadow"
        android:orientation="vertical">
Sudhir singh
źródło
wielkie dzięki sir, twój kod wydaje się być w porządku ...
John dahat
1
@Johndahat its ok
Sudhir singh
1

Ya Mahdi aj --- dla RelativeLayout

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle">
            <gradient
                android:startColor="#7d000000"
                android:endColor="@android:color/transparent"
                android:angle="90" >
            </gradient>
            <corners android:radius="2dp" />
        </shape>
    </item>

    <item
        android:left="0dp"
        android:right="3dp"
        android:top="0dp"
        android:bottom="3dp">
        <shape android:shape="rectangle">
            <padding
                android:bottom="40dp"
                android:top="40dp"
                android:right="10dp"
                android:left="10dp"
                >
            </padding>
            <solid android:color="@color/Whitetransparent"/>
            <corners android:radius="2dp" />
        </shape>
    </item>
</layer-list>
سیدرسول میرعظیمی
źródło
1

Wiem, że to późno, ale może to komuś pomóc.

Możesz użyć constraintLayout i dodać następującą właściwość w xml,

        android:elevation="4dp"
harishanth raveendren
źródło
0

Znalazłem najlepszy sposób na rozwiązanie tego problemu.

  1. Musisz ustawić jednolite prostokątne tło w układzie.

  2. Użyj tego kodu - ViewCompat.setElevation(view , value)

  3. W nadrzędnym zestawie układów android:clipToPadding="false"

Sarthak Gandhi
źródło
2
Jeśli nie wiesz, oto aktualna implementacja ViewCompat.setElevation()metody w klasie ViewCompat:public void setElevation(View view, float elevation) {} . Jak widać, nie jest zaimplementowany. Naprawdę wątpię, żeby to pomogło i naprawdę zastanawiam się, czy rzeczywiście przetestowałeś swoją własną odpowiedź, lol
mradzinski