【问题标题】:CardView elevation shadow not centered?CardView 高程阴影不居中?
【发布时间】:2018-12-31 17:46:32
【问题描述】:

我有一个CardView 定义为

<androidx.cardview.widget.CardView
    android:layout_width="70dp"
    android:layout_height="70dp"
    app:cardCornerRadius="35dp"
    app:cardElevation="10dp">
    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="fitXY"
        android:src="@drawable/ic_user_default"/>
</androidx.cardview.widget.CardView>

但不知何故,我得到了这个奇怪的阴影,我无法弄清楚为什么?

我想要一个圆形 CardView,周围有一个圆形阴影,但我却在右下角得到一个阴影。

我错过了什么?

我尝试了一些东西,这就是我的结论。

CardView 位于具有 wrap_contentlayout_height 的 RelativeLayout 内。我猜这只是包装 CardView ,没有它的影子。看看下面的例子。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center">
    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
        <androidx.cardview.widget.CardView
            android:layout_width="70dp"
            android:layout_height="70dp"
            app:cardCornerRadius="35dp"
            app:cardElevation="10dp">
        </androidx.cardview.widget.CardView>
    </RelativeLayout>

    <androidx.cardview.widget.CardView
        android:layout_width="70dp"
        android:layout_height="70dp"
        app:cardCornerRadius="35dp"
        app:cardElevation="10dp">
    </androidx.cardview.widget.CardView>

</LinearLayout>

这将显示为

那么这就引出了一个问题,为什么它环绕 CardView 而不是 CardView 的阴影? 还有一个问题。如何使 CardView 的阴影居中?如果你仔细观察第二个 CardView,阴影是有重力的。

【问题讨论】:

  • 是图片PNG?
  • 请检查此示例 sn-p here
  • 您设备的 Android 版本是多少?图片是圆形的?你是如何在卡片视图中加载这张图片的?
  • @aliusman 图片不是png。它的jpg
  • @snti 我使用的是 Android 8。图像不是圆形的。我通过分配src 来加载它,因为它在卡片视图中,所以它是循环的。

标签: android android-cardview androidx


【解决方案1】:

我建议你看看android documentation for shadows

你说:

CardView 位于具有 wrap_contentlayout_height 的 RelativeLayout 内。我猜这只是包装 CardView ,没有它的影子。那么这就引出了一个问题,为什么它会环绕 CardView 而不是 CardView 的阴影?

以下回答原因:

阴影由提升视图的父级绘制,因此受到标准视图裁剪,默认情况下由父级裁剪。

还有:

视图的背景可绘制对象的边界决定了其阴影的默认形状。考虑这个使用背景可绘制对象定义的视图:

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

背景可绘制对象定义为圆角矩形:

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

视图用圆角投射阴影,因为背景可绘制对象定义了视图的轮廓。提供自定义轮廓会覆盖视图阴影的默认形状。

您已经通过app:cardCornerRadius="35dp" 而不是自定义背景可绘制对象实现了这一点(这同样可以接受,尽管我认为如果您将来需要它用于其他视图,添加这些信息可能会有所帮助)。

要回答问题如何使 CardView 的阴影居中?您可以查看material design guidelines。根据 Material Design,阴影应该来自环境光(前光源)和主光(顶部光源):

这些光源的仰角在android框架中默认分别为90度和45度,并且不能更改,因为这与Material Design不一致。但是,如果您想创建具有自定义角度的自定义阴影,您可以使用渐变可绘制对象并将其设置为头部下方here 中描述的阴影使用Shape Drawable(实现阴影的新方法)

基本上,您需要使用android.graphics.Paint 类中的setShadowLayer 方法。

希望这会有所帮助!

【讨论】:

    【解决方案2】:

    CardView 阴影的偏差取决于它在屏幕中的位置。如下图所示,当CardView被放置在屏幕的左侧或右侧时,它的影子也会偏向左侧或右侧。

    但是,AFAIK,我们无法控制CardView 的阴影透视图,因为它没有属性可以更改。如果你想有一个自定义的方向阴影,你应该自己做。

    【讨论】:

      猜你喜欢
      • 2017-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-05
      • 1970-01-01
      • 2018-08-11
      • 1970-01-01
      • 2018-12-02
      相关资源
      最近更新 更多