【问题标题】:How to add a shadow above a view in android如何在android中的视图上方添加阴影
【发布时间】:2016-03-20 11:20:09
【问题描述】:

我有一个将服务器作为页脚标题的视图。它只是一个视图,您可能会将其视为按钮、文本视图或布局(我真的对任何事情都持开放态度)。这是xml

<RelativeLayout>
   <ScrollView >… </ScrollView> //match parent width and height
   <MyBottomView/> // align parent bottom
 </RelativeLayout>

所以你可以看到 ScrollView 在 MyBottomView 下方滚动。我想给 MyBottomView 添加一个顶部阴影,让它看起来更像 Material Design。我该怎么做?

【问题讨论】:

标签: android android-layout material-design


【解决方案1】:

如果您只需要在视图的一侧(例如顶部)有阴影,您可以在它之前添加另一个视图并使用渐变阴影作为其背景。

这是你必须存储在drawable文件夹中的渐变文件top_shadow_gradient.xml

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

这是一个示例布局如何使用它:

<?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:background="@android:color/transparent"
    android:orientation="vertical">

    <View
        android:layout_width="match_parent"
        android:layout_height="8dp"
        android:background="@drawable/top_shadow_gradient" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#ffffff"
        android:orientation="vertical"
        android:paddingTop="8dp">

        <!-- Put your content here-->

    </LinearLayout>

</LinearLayout>

重要提示: 根布局必须是透明的 (android:background="@android:color/transparent") 并且您的“内容”布局需要有白色背景 (android:background="#ffffff")。

结果如下:

【讨论】:

  • 唯一对我有用的解决方案,但我总是在乞求阴影时得到一条陌生的白线。
  • 将 endcolor 设置为完全透明的黑色 #0000 删除了白色。然而,这种策略虽然简单,但不会像光照那样产生完全正确的阴影
  • 请参阅 here 以获取有关如何使用 Paint.setXferemode() 进行此操作的指针
  • 圆角半径怎么样?
【解决方案2】:

这里有一些解决这个问题的方法 - 选择你最好的:

Android中没有这样的属性,用来显示阴影。但可能的方法是:

  1. 添加一个灰色的普通 LinearLayout,在上面添加您的实际布局,底部和右侧的边距等于 1 或 2 dp。
  1. 有一个带有阴影的 9-patch 图像,并将其设置为线性布局的背景。

还有另一个解决该问题的方法是实现一个图层列表作为线性布局的背景。

将 background_with_shadow.xml 文件添加到res/drawable。包含:

<?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="@android:color/darker_gray" />
        <corners android:radius="5dp"/>
        </shape>
    </item>
    <item android:right="1dp" android:left="1dp" android:bottom="2dp">
        <shape 
            android:shape="rectangle">
        <solid android:color="@android:color/white"/>
        <corners android:radius="5dp"/>
        </shape>
    </item>
</layer-list>

然后在您的 LinearLayout 中添加图层列表作为背景。

<LinearLayout
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:background="@drawable/background_with_shadow"/>

您也可以阅读:http://odedhb.blogspot.com/2013/05/android-layout-shadow-without-9-patch.html

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" 
    android:padding="10dp"
    android:background="#CC55CC">
    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <TableLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:stretchColumns="0">
            <TableRow>
                <LinearLayout
                    android:id="@+id/content"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content">
                    <TextView  
                        android:layout_width="fill_parent" 
                        android:layout_height="wrap_content"
                        android:background="#FFFFFF" 
                        android:text="@string/hello" />
                </LinearLayout>
                <View
                    android:layout_width="5dp"
                    android:layout_height="fill_parent"
                    android:layout_marginTop="5dp"
                    android:background="#55000000"/>
            </TableRow>
        </TableLayout>
        <View
            android:layout_width="fill_parent"
            android:layout_height="5dp"
            android:layout_marginLeft="5dp"
            android:background="#55000000"/>
    </LinearLayout>
</FrameLayout>
  • 您还可以使用特定的可绘制表单 Android 资源来模拟阴影效果。看看:Android View shadow 或阅读下面的帖子:

我使用的是 Android Studio 0.8.6,但我找不到:

android:background="@drawable/abc_menu_dropdown_panel_holo_light"

所以我发现了这个:

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

它看起来像这样:


如果您对干净的 Material Design 效果感兴趣,请阅读以下文档:

【讨论】:

    【解决方案3】:

    我为此找到的技巧是将您的视图包装在父级中并使用旋转。例如。如果你有一个卡片视图并且正在向它添加高度,你可以像这样放置两个旋转来实现上方而不是下方的阴影:

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:clipToPadding="false"
        android:paddingBottom="10dp"
        android:rotation="180">
    
        <android.support.v7.widget.CardView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:rotation="180"
            app:cardElevation="8dp">
        <!--Card view content-->
        </android.support.v7.widget.CardView>
    </RelativeLayout>
    

    这给出了类似于所附屏幕截图的内容。

    这仍然存在问题 - 这需要在父布局上设置 paddingBottom,这意味着很明显,布局上方的任何可滚动兄弟都不会低于它。

    因此,即使在当今高度和轮廓提供者的时代,最好还是添加一个半透明视图。 :(

    【讨论】:

    • 另一个问题是它会将 CardView 中的任何内容颠倒过来!
    • 是的,这需要让孩子也旋转 180 度。我知道,不好。
    • 它的老套路不是真正的解决方案。
    • 完全。这就是我在回答中开始说的:)
    • 虽然很老套,但不幸的是,这是最好的解决方案。添加形状有那个可怕的白色带,比这个解决方案优雅得多
    【解决方案4】:

    我通过使用 ConstraintLayouts 更新了 Ivo's 出色的答案。

    可绘制:shadow_top.xml

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

    布局

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto"
      android:layout_width="match_parent"
      android:layout_height="match_parent">
    
        <androidx.constraintlayout.widget.ConstraintLayout
          android:id="@+id/cl_topView"
          android:layout_width="match_parent"
          android:layout_height="0dp"
          app:layout_constraintBottom_toTopOf="@id/cl_bottomView"
          app:layout_constraintStart_toStartOf="parent"
          app:layout_constraintTop_toTopOf="parent">
          
             ... nested views
    
        </androidx.constraintlayout.widget.ConstraintLayout>
    
        <View
          android:id="@+id/v_shadowTop"
          android:layout_width="match_parent"
          android:layout_height="3dp"
          android:background="@drawable/shadow_top"
          app:layout_constraintStart_toStartOf="parent"
          app:layout_constraintBottom_toTopOf="@id/cl_bottomView"/>
    
       <androidx.constraintlayout.widget.ConstraintLayout
          android:id="@+id/cl_bottomView"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          app:layout_constraintBottom_toBottomOf="parent"
          app:layout_constraintStart_toStartOf="parent"
          app:layout_constraintTop_toBottomOf="@id/cl_topView">
    
             ... nested views
    
        </androidx.constraintlayout.widget.ConstraintLayout>
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    结果: 按照上面的步骤,我可以得到下图中箭头所指的顶部阴影。

    对于 Android 开发新手:

    高度调整: 阴影的高度由视图的“v_shadowTop”高度(当前为 3dp)控制。

    渐变调整: 渐变的颜色由“shadow_top.xml”drawable 中 startColor(当前为 000000)和 endColor(当前为 ffffff)的最后六个字符(十六进制代码)控制。

    透明度由 shadow_top.xml 可绘制对象中的 startColor(当前为 40)和 endColor(当前为 10)的前两个字符控制。

    【讨论】:

      【解决方案5】:

      仅顶部阴影:

      <layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
      
      <item>
          <shape>
              <padding
                  android:top="@dimen/_2sdp" />
              <solid android:color="@color/red" />
              <corners android:radius="@dimen/_8sdp" />
          </shape>
      </item>
      
      <!-- Background -->
      <item>
          <shape>
              <solid android:color="@color/white" />
              <corners android:radius="@dimen/_8sdp" />
          </shape>
      </item>
      

      如果您希望阴影出现在其他区域,请添加填充 bottomrightleft

      结果:

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-11-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-14
        • 2020-04-21
        • 2019-08-13
        相关资源
        最近更新 更多