13

I am trying to use a BottomSheet in my layout. The root view is an CoordinatorLayout and I want to set Elevation on top for the Bottom Sheet so i am setting it with a high value (50dp), however it is not showing when the app runs but it appears on android studio design tool.

I have tried to set background for the sheet with a solid color instead of gradient but it still did work. I also tried to use Shadow shapes but it does not give the same elevation appearance.

here is my XML

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.atefhares.StartActivity"
    android:clipToPadding="false">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <LinearLayout
            android:id="@+id/DetailsView"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:orientation="vertical">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Details Should be shown here"
                android:id="@+id/textView"
                android:textSize="25sp"
                android:padding="20dp" />
        </LinearLayout>

        <fragment xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:tools="http://schemas.android.com/tools"
            android:id="@+id/map"
            android:name="com.google.android.gms.maps.SupportMapFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:context="com.atefhares.Start_Activity" />


    </LinearLayout>
    <android.support.v4.widget.SlidingPaneLayout
        android:id="@+id/bottom_sheet"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:behavior_peekHeight="70dp"
        app:layout_behavior="android.support.design.widget.BottomSheetBehavior"
        android:background="@drawable/gradiant"
        android:fillViewport="true"
        android:elevation="50dp">


        <include layout="@layout/bottom_sheet_layout"/>

    </android.support.v4.widget.SlidingPaneLayout>

</android.support.design.widget.CoordinatorLayout>

Edit: bottom_sheet_layout.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true"
    android:orientation="vertical">


    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="70dp"
        android:background="@color/colorPrimary"
        android:padding="10dp"
        android:id="@+id/inviteLL">

        <ImageView
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:id="@+id/imageView"
            android:background="@drawable/invite_icon"
            android:layout_margin="5dp"
            android:layout_gravity="center_vertical" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Invite Friends"
            android:textSize="22sp"
            android:textColor="#ffffff"
            android:padding="10dp"
            android:fontFamily="sans-serif-condensed"
            android:gravity="center_vertical"
            android:id="@+id/inviteTV"

            android:layout_gravity="center_vertical"
            android:layout_weight="1" />

        <ImageView
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:id="@+id/arrowIV"
            android:layout_gravity="center_vertical"
            android:background="@drawable/arrow_up" />
    </LinearLayout>


    <ListView
        android:layout_width="match_parent"
        android:layout_height="fill_parent"
        android:id="@+id/usersLV"
        android:dividerHeight="1dp"
        android:divider="#ffffff"
        android:background="#ffffff" />

</LinearLayout>

So how can I make the elevation shows on top of the Bottom Sheet

Any one can help, please ?

Atef Hares
  • 4,715
  • 3
  • 29
  • 61

4 Answers4

1

Try this,

<android.support.v4.widget.SlidingPaneLayout
        android:id="@+id/bottom_sheet"
xmlns:slide_panel="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:behavior_peekHeight="70dp"
      app:layout_behavior="android.support.design.widget.BottomSheetBehavior"
        android:background="@drawable/gradiant"
        android:fillViewport="true"
        slide_panel:elevation="50dp">
  • elevation is only working for greater than 5.0 devices – Karthik Sridharan Sep 07 '16 at 06:38
  • Elevation works everywhere on 5+ devices. It's a View attribute. But here it doesn't work because of something the BottomSheetBehavior does, the modification you suggest: using slide_panel:elevation in place of android:elevation is pointless. – Daniele Segato Sep 07 '16 at 08:23
1

According to the google guidelines with the android:elevation is not possible (Also you can read more about the keyligth).

Anyway on the most common cases when you scroll up the "BottomSheet" a semitransparent layer appears behind the "BottomSheet", this helps to keep the user focus on the "BottomSheet" actions, like these examples.

If anyway you want a top shadow you can set a drawable background with gradient like this (shadow_top.xml):

<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
    android:angle="90"
    android:centerColor="#000000"
    android:endColor="@android:color/transparent"
    android:startColor="#000000"
    android:type="linear" />

And your SlidingPanelLayout will be:

<android.support.v4.widget.SlidingPaneLayout
    android:id="@+id/bottom_sheet"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:behavior_peekHeight="95dp"
    android:paddingTop="25dp"
    app:layout_behavior="android.support.design.widget.BottomSheetBehavior"
    android:background="@drawable/shadow_top"
    android:fillViewport="true"
    >

Best regards.

Vinicius DSL
  • 1,839
  • 1
  • 18
  • 26
  • no where in the google guidelines it say it is not possible – Daniele Segato Sep 08 '16 at 17:52
  • On the guidelines says "Combined shadow from key and ambient lights" and you can see how the lights are pointing. – Vinicius DSL Sep 08 '16 at 18:35
  • yep. It doesn't say no shadow below. It's combined. And ambient light has no direction. – Daniele Segato Sep 08 '16 at 18:40
  • true, but look at "Shadow cast by key light", there is no shadow on the top, you can assume the direction of the key light (I didn't see an option to change the key light on android) https://en.wikipedia.org/wiki/Key_light – Vinicius DSL Sep 08 '16 at 18:46
  • i've a bottomsheetlayout in my app it has elevation and i can SEE the elevation on top. It's LOT less visible then how it would be if bottom (16dp) but It is visible. So your argument is invalid. The ambient shadow is visible top. – Daniele Segato Sep 08 '16 at 19:24
  • Again.. I said "look at "SHADOW CAST BY KEY LIGHT", there is no shadow on the top" I know that shadow on the top it's the result of ambient light, most part of the final shadow is caused by the "Shadow cast by key light" and until I know, on android, you can't change/reverse this light. – Vinicius DSL Sep 08 '16 at 19:34
0

Do not forget that to draw shadow you must use hardwareAccelerated drawing

hardwareAccelerated = true enter image description here

hardwareAccelerated = false enter image description here

See Android Hardware Acceleration for details

Danil Onyanov
  • 210
  • 1
  • 4
  • 16
0

The answer is: no, it is not possible (unless you create your own view custom with an elevation feature on top).

Elevetion is not meant to be visible in the top of a view, but in the bottom, on the right and on the left.

If you see closely on the official Material Design guidelines, you can see that the bottom bar simply don't have it (do not confuse with the gray space between the card and the bottom bar).

enter image description here

For example: import Card View sample from Android Studio and play with it with emulator or your device. You will see that if you increment the elevation value, the view will have his shadow everywhere except on top (see second image below).

enter image description here

Another example is given by importing Elevation Basic.

EDIT

Following code is taken from Card View sample. There is a layout containing a CardView with elevation. Whenever you change the elevation, you will always see shadow everywhere, but not on top (the code was tested with Lollipop and Marshmallow).

<LinearLayout android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:orientation="vertical"
              android:paddingBottom="@dimen/activity_vertical_margin"
              android:paddingTop="@dimen/activity_vertical_margin"
              android:paddingLeft="@dimen/activity_horizontal_margin"
              android:paddingRight="@dimen/activity_horizontal_margin"
    >
    <android.support.v7.widget.CardView
        android:id="@+id/cardview"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:elevation="100dp"
        card_view:cardBackgroundColor="@color/cardview_initial_background"
        card_view:cardCornerRadius="8dp"
        android:layout_marginLeft="@dimen/margin_large"
        android:layout_marginRight="@dimen/margin_large"
        >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/margin_medium"
            android:text="@string/cardview_contents"
            />
    </android.support.v7.widget.CardView>

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/margin_large"
        android:orientation="horizontal"
        >
        <TextView
            android:layout_width="@dimen/seekbar_label_length"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:text="@string/cardview_radius_seekbar_text"
            />
        <SeekBar
            android:id="@+id/cardview_radius_seekbar"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/margin_medium"
            />
    </LinearLayout>

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        >
        <TextView
            android:layout_width="@dimen/seekbar_label_length"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:text="@string/cardview_elevation_seekbar_text"
            />
        <SeekBar
            android:id="@+id/cardview_elevation_seekbar"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/margin_medium"
            />
    </LinearLayout>
</LinearLayout>

JJ86
  • 5,055
  • 2
  • 35
  • 64
  • 1
    I appreciate the detailed response but this is simply not true. As you can see from the image here: https://developer.android.com/training/material/shadows-clipping.html a shadow can be clearly see on top of the view. The reason your image is showing no shadow on top is surely something else (some clipping in your layout for example). – Daniele Segato Sep 07 '16 at 17:02
  • @DanieleSegato thank you, but I clearly see the swadow on left, right and on bottom of the first rectangle. The example is taken from Google code, I have updated my answer. – JJ86 Sep 08 '16 at 07:38
  • @DanieleSegato this dude added more details, including a link to another guidelines: http://stackoverflow.com/a/39380091/2013835 . – JJ86 Sep 08 '16 at 07:46
  • I've my code right here with shadow on top using elevation. Working. For me. The issue was very stupid. For the original question it's something else. But the answer is NOT: "impossible to have shadow on top". – Daniele Segato Sep 08 '16 at 09:03
  • @DanieleSegato good, can you share the code in another answer, or maybe edit mine? – JJ86 Sep 08 '16 at 09:57
  • my code is a lot different from the one of the question. And the problem with it was a clipToPadding attribute that I totally failed to notice when I added the bounty to this question. I've no time now to investigate its code but I would guess it's something related to the background of the view – Daniele Segato Sep 08 '16 at 11:26
  • This answer is absolutely misleading. There IS shadow on top of the view with elevation. You can see the cuts in your example on every side of the card, not only on top, so it is an issue with your layout, not with the shadow on top. As a key to understand try to play with `clipToPadding` attribute. – the korovay Jun 11 '21 at 13:34
  • Thank you for your comments, will try out to improve that. – JJ86 Oct 08 '21 at 14:56