9

Recently, I stunned with a problem. On my android phone elements of the list or scroll views with the same elevation have different shadows related to their positioning. For example, views on the top of the screen have a small light shadow, whenever views on the bottom of the screen have more dark and strong shadow. Here is a screenshot from Google Keep application:

If you will look at first card view and last one, you will see different shadows

So, I thought that this is because of exactly Google Keep application. Maybe guys from Google decided to do that trick with shadows for their application. Thus, I created a sample application.

My layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        style="@style/AppButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:text="Test"/>

    <TextView
        style="@style/AppButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:text="Test"/>

    <TextView
        style="@style/AppButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:text="Test"/>

    <TextView
        style="@style/AppButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:text="Test"/>

    <TextView
        style="@style/AppButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:text="Test"/>

    <TextView
        style="@style/AppButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:text="Test"/>

    <TextView
        style="@style/AppButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:text="Test"/>

</LinearLayout>

My styles:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

    <style name="AppButton">
        <item name="android:background">@color/colorAccent</item>
        <item name="android:elevation">4dp</item>
        <item name="android:gravity">center</item>
        <item name="android:padding">16dp</item>
        <item name="android:textColor">@android:color/white</item>
    </style>

</resources>

And the output is:

enter image description here

As you see, we have the same effect (top view has a small shadow, bottom view have a big shadow). So my questions are:

  1. What I did wrong?
  2. How can I achieve the same shadow for all views (not different by their positions)?
  3. Also, I haven't found any explanations in docs, so where I can read about that phenomenon?
  4. Does it happen on all devices or only on specific?

P.S.: I have Nexus 5X, Android 7.1.2.

UPD: An important mention that from Android Studio Preview Window everything is fine. Every view has the same shadow as other. But on a real device, you can see the difference.

piet.t
  • 11,718
  • 21
  • 43
  • 52
Michael Spitsin
  • 2,539
  • 2
  • 19
  • 29
  • you didnt do anything wrong thats how cards are suppose to look, the shadow is at the bottom because the light source is suppose to be from the top. https://material.io/guidelines/components/cards.html# https://material.io/guidelines/material-design/elevation-shadows.html#elevation-shadows-shadows – tyczj Jul 11 '17 at 13:13
  • @tyczj Actually, I've got your explanation and realized that we talk about different things. All shadows are casted from top to the bottom, but if you will look on top views in the list and on the bottom views in the list, you will see, that shadows are different, but for both views `elevation = 4dp`. But for user, it looks like views on the top of the screen have 2-3dp elevation and views on the bottom of the screen have 4-5dp elevation – Michael Spitsin Jul 11 '17 at 13:24

1 Answers1

12

Shadows generated by Elevation API are positioned in 3D space, which means that the look of each shadow is affected not only by its elevation value, but also by shadow caster's x and y position on screen. It's pretty much like in the real world - objects beneath a light source cast shorter shadows than objects further away.

Take a closer look at the first image you posted. Shadows are longer on left edges of the left cards and on right edges of the right cards than on the edges at the horizontal center.

Ad. 1. Nothing. It just works that way.

Ad. 2. It's not possible using Elevation API. You can draw shadows by yourself.

Ad. 3. Don't know, sorry.

Ad. 4. All devices.

Ad. UPD. Shadows in the editor are static, so there's no effect you're observing.

enter image description here

Zielony
  • 16,239
  • 6
  • 34
  • 39