Cień widoku Androida

102

Rozejrzałem się i nie mogłem znaleźć właściwego sposobu, aby to zrobić. Chcę mieć następujące efekty cienia w moich widokach: wprowadź opis obrazu tutaj

wprowadź opis obrazu tutaj

Szczerze mówiąc, nie wiem, czy ten drugi to efekt cienia. Jakieś pomysły?

Longwalker
źródło
1
Masz na myśli to? stackoverflow.com/questions/4406524/… (sprawdź najwyższą odpowiedź, a nie zaznaczoną odpowiedź)
Luke Vo
1
@DatVM, dzięki, wydaje się, że to załatwia sprawę, ale myślałem, że może są wbudowane narzędzia w Android SDK. Na przykład dodanie cieni do układów liniowych przez dodanie kilku wierszy kodu: P
longwalker
Podobne pytanie - stackoverflow.com/q/52954743/9640177 - dodawanie cienia do wektora do rysowania
mayank1513

Odpowiedzi:

158

Wiem, że na to pytanie już odpowiedziano, ale chcę, abyś wiedział, że znalazłem drawablena stronie, Android Studioktóra jest bardzo podobna do zdjęć, które masz w pytaniu: Spójrz na to:

android:background="@drawable/abc_menu_dropdown_panel_holo_light"

To wygląda tak:

wprowadź opis obrazu tutaj

Mam nadzieję, że to będzie pomocne

Edytować

Powyższa opcja dotyczy starszych wersji, Android Studiowięc możesz jej nie znaleźć. W przypadku nowszych wersji:

android:background="@android:drawable/dialog_holo_light_frame"

Co więcej, jeśli chcesz mieć swój własny niestandardowy kształt, proponuję użyć programu do rysowania, takiego jak Photoshopi narysować go.

wprowadź opis obrazu tutaj

Nie zapomnij zapisać go jako .9.pngpliku (przykład my_background.9.png:)

Przeczytaj dokumentację: Draw 9-patch

Edytuj 2

Jeszcze lepszym i mniej pracowitym rozwiązaniem jest użycie CardViewzestawu i, app:cardPreventCornerOverlap="false"aby zapobiec nakładaniu się widoków na granice:

<android.support.v7.widget.CardView
    android:id="@+id/card_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:cardCornerRadius="2dp"
    app:cardElevation="2dp"
    app:cardPreventCornerOverlap="false"
    app:contentPadding="0dp">

    <!-- your layout stuff here -->

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

Upewnij się również, że uwzględniono najnowszą wersję w build.gradle, bieżącym pliku jest

compile 'com.android.support:cardview-v7:26.0.0'
Stóg
źródło
Dzięki, właściwie wygląda bardzo podobnie. Znalazłem też „układ kart Google” dla Androida i są całkiem fajne!
Longwalker
6
Niesamowite. To tylko informacja dla przyszłych widzów /<sdk-path>/extras/android/support.
theblang
2
A co z użyciemcardView
Alex Chengalan,
100

Używam Android Studio 0.8.6 i nie mogę znaleźć:

android:background="@drawable/abc_menu_dropdown_panel_holo_light"

więc zamiast tego znalazłem to:

android:background="@android:drawable/dialog_holo_light_frame"

i wygląda to tak:

wprowadź opis obrazu tutaj

Repozytorium
źródło
1
ale nie możemy dodać z nim promienia narożnika ?!
Fay007
40

umieszczenie tła @android:drawable/dialog_holo_light_frame, daje cień, ale nie można zmienić koloru tła ani stylu obramowania, więc lepiej jest skorzystać z jego cienia, a jednocześnie być w stanie umieścić tło za pomocą listy warstw

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!--the shadow comes from here-->
    <item
        android:bottom="0dp"
        android:drawable="@android:drawable/dialog_holo_light_frame"
        android:left="0dp"
        android:right="0dp"
        android:top="0dp">

    </item>

    <item
        android:bottom="0dp"
        android:left="0dp"
        android:right="0dp"
        android:top="0dp">
        <!--whatever you want in the background, here i preferred solid white -->
        <shape android:shape="rectangle">
            <solid android:color="@android:color/white" />

        </shape>
    </item>
</layer-list>

zapisz go w folderze do rysowania pod powiedz shadow.xml

aby przypisać go do widoku, w pliku układu xml ustaw jego tło

android:background="@drawable/shadow"
Mohamed Selim
źródło
Sprawdziłeś, czy działa? Drugi <item> nic nie robi. Nie mogę zmienić tego na przezroczyste lub zaokrąglone rogi.
zeeshan
2
Ze wszystkiego, czego próbowałem, to jedyna rzecz, która działa, dzięki.
Shyam Sunder
1
fantastyczne rozwiązanie
user1974368
34

Utwórz card_background.xml w folderze res / drawable 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>
    <shape android:shape="rectangle">
        <solid android:color="#BDBDBD"/>
        <corners android:radius="5dp"/>
    </shape>
</item>

<item
    android:left="0dp"
    android:right="0dp"
    android:top="0dp"
    android:bottom="2dp">
    <shape android:shape="rectangle">
        <solid android:color="#ffffff"/>
        <corners android:radius="5dp"/>
    </shape>
</item>
</layer-list>

Następnie dodaj następujący kod do elementu, do którego chcesz zastosować układ karty

android:background="@drawable/card_background"

poniższy wiersz określa kolor cienia karty

<solid android:color="#BDBDBD"/>
Vivek Varma
źródło
10
To naprawdę nie jest cień - ponieważ nie blaknie. Bardziej przypomina granicę po dwóch stronach.
zakaz geoinżynierii
to nie jest cień
ShadeToD
24

CardView zapewnia prawdziwy cień w systemie Android 5+ i ma bibliotekę wsparcia. Po prostu zawiń nim swój widok i gotowe.

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

Wymaga kolejnej zależności.

dependencies {
    ...
    compile 'com.android.support:cardview-v7:21.0.+'
}
Ilya Gazman
źródło
1
To jedyna prawidłowa odpowiedź, ponieważ tylko CardViewróżne poziomy cienia dla różnych wysokości w trybie zgodności.
Jarett Millard,
Polecam MaterialCardView, ponieważ jest bardziej przejrzysty i ma więcej możliwości.
H. Farid
12

To może być późno, ale dla tych, którzy wciąż szukają odpowiedzi na to pytanie, znalazłem projekt w git hub i jest to jedyny, który faktycznie odpowiada moim potrzebom. android-materialshadowninepatch

Po prostu dodaj tę linię do zależności build.gradle

compile 'com.h6ah4i.android.materialshadowninepatch:materialshadowninepatch:0.6.3'

Twoje zdrowie. Kciuki w górę dla twórcy! happycodings

ralphgabb
źródło
Hej @ralphgabb, czy to nadal działa dobrze dla Ciebie, czy masz lepsze rozwiązanie dla urządzeń pre Lollipop?
Swapnil
@Swapnil nie jestem pewien, czy AndroidX obsługuje to teraz, ale nie obsługuję już urządzeń sprzed wersji Marshmallow.
ralphgabb
5

Wiem, że to głupio zepsute,
ale jeśli chcesz wspierać w ramach v21, oto moje osiągnięcia.

rectangle_with_10dp_radius_white_bg_and_shadow.xml

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

    <!-- Shadow layers -->
    <item
        android:left="1dp"
        android:right="1dp"
        android:top="3dp">
        <shape>
            <corners android:radius="10dp" />
            <padding
                android:bottom="1.8dp"
                android:left="1dp"
                android:right="1dp"
                android:top="1dp" />
            <solid android:color="@color/shadow_hack_level_1" />
        </shape>
    </item>
    <item
        android:left="1dp"
        android:right="1dp"
        android:top="3dp">
        <shape>
            <corners android:radius="10dp" />
            <padding
                android:bottom="1.8dp"
                android:left="1dp"
                android:right="1dp"
                android:top="1dp" />
            <solid android:color="@color/shadow_hack_level_2" />
        </shape>
    </item>
    <item
        android:left="1dp"
        android:right="1dp"
        android:top="3dp">
        <shape>
            <corners android:radius="10dp" />
            <padding
                android:bottom="1.8dp"
                android:left="1dp"
                android:right="1dp"
                android:top="1dp" />
            <solid android:color="@color/shadow_hack_level_3" />
        </shape>
    </item>
    <item
        android:left="1dp"
        android:right="1dp"
        android:top="3dp">
        <shape>
            <corners android:radius="10dp" />
            <padding
                android:bottom="1.8dp"
                android:left="1dp"
                android:right="1dp"
                android:top="1dp" />
            <solid android:color="@color/shadow_hack_level_4" />
        </shape>
    </item>
    <item
        android:left="1dp"
        android:right="1dp"
        android:top="3dp">
        <shape>
            <corners android:radius="10dp" />
            <padding
                android:bottom="1.8dp"
                android:left="1dp"
                android:right="1dp"
                android:top="1dp" />
            <solid android:color="@color/shadow_hack_level_5" />
        </shape>
    </item>
    <item
        android:left="1dp"
        android:right="1dp"
        android:top="3dp">
        <shape>
            <corners android:radius="10dp" />
            <padding
                android:bottom="1.8dp"
                android:left="1dp"
                android:right="1dp"
                android:top="1dp" />
            <solid android:color="@color/shadow_hack_level_6" />
        </shape>
    </item>
    <item
        android:left="1dp"
        android:right="1dp"
        android:top="3dp">
        <shape>
            <corners android:radius="10dp" />
            <padding
                android:bottom="1.8dp"
                android:left="1dp"
                android:right="1dp"
                android:top="1dp" />
            <solid android:color="@color/shadow_hack_level_7" />
        </shape>
    </item>
    <item
        android:left="1dp"
        android:right="1dp"
        android:top="3dp">
        <shape>
            <corners android:radius="10dp" />
            <padding
                android:bottom="1.8dp"
                android:left="1dp"
                android:right="1dp"
                android:top="1dp" />
            <solid android:color="@color/shadow_hack_level_8" />
        </shape>
    </item>
    <item
        android:left="1dp"
        android:right="1dp"
        android:top="3dp">
        <shape>
            <corners android:radius="10dp" />
            <padding
                android:bottom="1.8dp"
                android:left="1dp"
                android:right="1dp"
                android:top="1dp" />
            <solid android:color="@color/shadow_hack_level_9" />
        </shape>
    </item>
    <item
        android:left="1dp"
        android:right="1dp"
        android:top="3dp">
        <shape>
            <corners android:radius="10dp" />
            <padding
                android:bottom="1.8dp"
                android:left="1dp"
                android:right="1dp"
                android:top="1dp" />
            <solid android:color="@color/shadow_hack_level_10" />
        </shape>
    </item>

    <!-- Background layer -->
    <item>
        <shape>
            <solid android:color="@android:color/white" />
            <corners android:radius="10dp" />
        </shape>
    </item>

</layer-list>

rectangle_with_10dp_radius_white_bg_and_shadow.xml (v21)

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="@android:color/white" />
    <corners android:radius="10dp" />
</shape>

view_incoming.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/rectangle_with_10dp_radius_white_bg_and_shadow"
    android:elevation="7dp"
    android:gravity="center"
    android:minWidth="240dp"
    android:minHeight="240dp"
    android:orientation="horizontal"
    android:padding="16dp"
    tools:targetApi="lollipop">

    <TextView
        android:id="@+id/text1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        tools:text="Hello World !" />

</LinearLayout>

Oto wynik:

Zgodnie z wersją 21 (to jest to, co stworzyłeś za pomocą XML) wprowadź opis obrazu tutaj

Powyżej wersji 21 (rzeczywiste renderowanie elewacji) wprowadź opis obrazu tutaj

  • Jedyną znaczącą różnicą jest to, że będzie zajmować wewnętrzną przestrzeń z widoku, więc rzeczywisty obszar zawartości może być mniejszy niż > = urządzenia Lollipop .
wonsuc
źródło
3

Jeśli potrzebujesz odpowiednich cieni do nałożenia, musisz wykonać następujące czynności.

Rozważmy ten widok, zdefiniowany za pomocą rysowanego tła:

<TextView
    android:id="@+id/myview"
    ...
    android:elevation="2dp"
    android:background="@drawable/myrect" />

Tło do rysowania jest definiowane jako prostokąt z zaokrąglonymi narożnikami:

<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">
    <solid android:color="#42000000" />
    <corners android:radius="5dp" />
</shape>

To jest zalecany sposób stosowania cieni, sprawdź to https://developer.android.com/training/material/shadows-clipping.html#Shadows

Shangeeth Sivan
źródło
2

Użyj właściwości elewacji dla efektu cienia:

<YourView
    ...
    android:elevation="3dp"/>
Ofek Ashery
źródło
Korzystanie z Elevation wymaga, aby urządzenie działało Lollipop.
Shane Rowatt
2

Utwórz tło, które można narysować w ten sposób, aby pokazać zaokrąglony cień.

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Drop Shadow Stack -->
    <item>
        <shape>
            <corners android:radius="4dp" />
            <padding android:bottom="1dp" android:left="1dp"
                     android:right="1dp"  android:top="1dp" />
            <solid android:color="#00CCCCCC" />
        </shape>
    </item>
    <item>
        <shape>
            <corners android:radius="4dp" />
            <padding android:bottom="1dp" android:left="1dp"
                     android:right="1dp"  android:top="1dp" />
            <solid android:color="#10CCCCCC" />
        </shape>
    </item>
    <item>
        <shape>
            <corners android:radius="4dp" />
            <padding android:bottom="1dp" android:left="1dp"
                     android:right="1dp"  android:top="1dp" />
            <solid android:color="#20d5d5d5" />
        </shape>
    </item>
    <item>
        <shape>
            <corners android:radius="6dp" />
            <padding android:bottom="1dp" android:left="1dp"
                     android:right="1dp"  android:top="1dp" />
            <solid android:color="#30cbcbcb" />
        </shape>
    </item>
    <item>
        <shape>
            <corners android:radius="4dp" />
            <padding android:bottom="1dp" android:left="1dp"
                     android:right="1dp"  android:top="1dp" />
            <solid android:color="#50bababa" />
        </shape>
    </item>

    <!-- Background -->
    <item>
        <shape>
            <solid android:color="@color/gray_100" />
            <corners android:radius="4dp" />
        </shape>
    </item>
</layer-list>
gaurav iqlance
źródło
Dodaj opis również do kodu, który podałeś.
Mangaldeep Pannu
Bardzo ładne rozwiązanie tylko xml
Bruno Bieri,
2

To pytanie może być stare, ale dla każdego, kto w przyszłości chce prostego sposobu na uzyskanie złożonych efektów cienia, sprawdź moją bibliotekę tutaj https://github.com/BluRe-CN/ComplexView

Korzystając z biblioteki, możesz zmieniać kolory cieni, dostosowywać krawędzie i wiele więcej. Oto przykład, jak osiągnąć to, czego szukasz.

<com.blure.complexview.ComplexView
        android:layout_width="400dp"
        android:layout_height="600dp"
        app:radius="10dp"
        app:shadow="true"
        app:shadowSpread="2">

        <com.blure.complexview.ComplexView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:color="#fdfcfc"
            app:radius="10dp" />
    </com.blure.complexview.ComplexView>

Aby zmienić kolor cienia, użyj app: shadowColor = "twój kod koloru".

BluRe.CN
źródło
1

użyj tego kształtu jako tła:

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

    <item android:drawable="@android:drawable/dialog_holo_light_frame"/>

    <item>
        <shape android:shape="rectangle">
            <corners android:radius="1dp" />
            <solid android:color="@color/gray_200" />
        </shape>
    </item>

</layer-list>
Panie Hosseini
źródło