如何向底部工作表视图添加阴影?

30

目前,使用Android设计库中的官方底部工作表组件实现时,顶边不会显示阴影。但是从各种模型和Material Design规范中看到,底部工作表包括某种离散阴影。

我认为阴影将有助于将底部工作表与主布局分开,特别是如果设置了Peek值和/或底部工作表始终可见。否则,它将与主布局及其项目混在一起。

我尝试了ViewCompat.setElevation(bottomSheet, 5); 和将android:elevation="5dp"设置给XML视图,但都没有成功。

来自Material Design规范的底部工作表示例


你在使用支持库或其他什么东西吗? - Alex Chengalan
@AlexChengalan 正确!v4、AppCompat和Design。 - Chris
尝试使用 app:cardElevation="5dp" - Alex Chengalan
2
但是我们在谈论底部表单。我使用LinearLayout作为表单的根视图。 - Chris
没有任何一个答案能够解决你的问题吗?或者为什么你不接受其中的一个答案呢? - mbo
4个回答

58

我知道阴影形状与高程图并不相同,但至少尝试一下。诀窍是使用app:layout_anchor将阴影剪裁到底部表。

activity_main.xml

<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">

<MapView
    android:id="@+id/map"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

<View
    android:id="@+id/shadow"
    android:layout_width="match_parent"
    android:layout_height="16dp"
    android:background="@drawable/shape_gradient_top_shadow"
    app:layout_anchor="@id/bottom_sheet" />

<FrameLayout
    android:id="@+id/bottom_sheet"
    android:layout_width="match_parent"
    android:layout_height="200dp"
    android:clipToPadding="false"
    app:layout_behavior="android.support.design.widget.BottomSheetBehavior" />

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

shape_gradient_top_shadow.xml

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

看起来像这样:

Bottom Sheet Shadow

编辑

使用自定义 ShadowView 可以获得更好的效果:

然后您可以执行以下操作:

<ShadowView
    android:id="@+id/shadow"
    android:layout_width="match_parent"
    android:layout_height="16dp"
    android:gravity="bottom"
    app:layout_anchor="@id/bottom_sheet" />

1
我无法让 android:elevation 生效。这是可以接受的。谢谢。 - ono
1
谢谢,但是当底部表单隐藏时,阴影仍然可见。我猜它也必须通过编程方式被隐藏。 - SagunKho
你可以在底部视图的顶部包含阴影,这样当它隐藏时,就会离开屏幕。 - Sofi Software LLC
我喜欢你的方法。谢谢你的帮助。 - André Luiz Reis
我认为需要注意的是,高程大多会在视图下方产生阴影而非上方。因此,对于像底部工作表这样的东西,这种方法很有效。 - caitcoo0odes

16

对于API Level 21及以上的版本,在父视图中设置以下内容。您也可以在底部工作表的根视图中尝试(我没有在根视图中尝试过)

android:background="@android:color/white"
android:elevation="16dp"
如果没有背景,则可以使用。
android:outlineProvider="bounds"
例如,我在一个嵌套的滚动视图中放置了我的表格。
<android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:clipToPadding="false"
  app:layout_behavior="android.support.design.widget.BottomSheetBehavior"
        android:elevation="16dp"
        android:outlineProvider="bounds"
        >

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

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

它只适用于底部阴影,而不适用于顶部阴影,因为“光”来自上角(请参见 fab 阴影)。 - Evgenii Vorobei
@EvgeniiVorobei 对我来说在 minSdk 21 上运行得很好。 - Aba

4

这个技巧是使用一个 CardView 作为父元素,并在 CardView 中设置高度。

<android.support.v7.widget.CardView
    android:layout_width="match_parent"
    android:background="#fff"
    android:clickable="true"
    android:focusable="true"
    app:behavior_hideable="true"
    app:layout_behavior="android.support.design.widget.BottomSheetBehavior"
    android:layout_height="140dp"
    app:cardElevation="8sp"
    card_view:cardCornerRadius="0dp">

      <!--The content of your Bottom sheet-->
        <android.support.constraint.ConstraintLayout
         android:layout_width="match_parent"
         android:layout_height="match_parent">
          .
          .
      </android.support.constraint.ConstraintLayout>

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

编辑

如果你要支持Kitkat及以下版本,这种技术并不是最好的解决方案。这是由于Cardview添加了额外的边距。


我需要在我的“BottomSheet”上添加阴影。由于该表从底部窥视,因此默认的“CardView”阴影不足。对我有用的是使用像这篇文章中建议的那样的“CardView”+更改阴影方向(https://blog.usejournal.com/playing-with-elevation-in-android-91af4f3be596)。 - Michal Vician

0

我认为这会对你有所帮助

首先像下面这样创建底部工作表,然后将其包含在您的主活动中

<LinearLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:app="http://schemas.android.com/apk/res-auto"
 android:id="@+id/bottom_sheet"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:orientation="vertical"
 app:behavior_hideable="true"
 app:behavior_peekHeight="56dp"
 android:layout_marginTop="0.5dp" // this margin depend on shadow area
 android:background="set you color"
 android:elevation="20dp" // chose your custom elevation 
 app:layout_behavior="@string/bottom_sheet_behavior">

    <LinearLayout
     android:layout_marginTop="1dp" // this margin depend on max elevation
     android:layout_width="match_parent"
     android:layout_height="200dp">

   </LinearLayout>

</LinearLayout>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接