【问题标题】:Android Drop Shadow on View视图上的 Android 投影
【发布时间】:2011-04-03 19:08:19
【问题描述】:

我已经对这方面的代码示例进行了广泛的搜索,但找不到任何东西。

特别是,我希望为我在 ImageView 中使用的 png drawable 添加阴影。这个 png drawable 是一个带有透明角的圆角矩形。

有人可以提供一个代码示例,说明如何在代码或 XML 中向视图添加体面的阴影吗?

【问题讨论】:

标签: android xml imageview shadow dropshadow


【解决方案1】:

您可以结合使用 Bitmap.extractAlpha 和 BlurMaskFilter 来为您需要显示的任何图像手动创建投影,但这仅在您的图像仅偶尔加载/显示一次时才有效,因为该过程很贵。

伪代码(甚至可以编译!):

BlurMaskFilter blurFilter = new BlurMaskFilter(5, BlurMaskFilter.Blur.OUTER);
Paint shadowPaint = new Paint();
shadowPaint.setMaskFilter(blurFilter);

int[] offsetXY = new int[2];
Bitmap shadowImage = originalBitmap.extractAlpha(shadowPaint, offsetXY);

/* Might need to convert shadowImage from 8-bit to ARGB here, can't remember. */

Canvas c = new Canvas(shadowImage);
c.drawBitmap(originalBitmap, offsetXY[0], offsetXY[1], null);

然后把 shadowImage 放到你的 ImageView 中。如果此图像从未更改但显示很多,您可以创建它并将其缓存在 onCreate 以绕过昂贵的图像处理。

即使这不起作用,也应该足以让你朝着正确的方向前进。

【讨论】:

  • 它有点工作......一旦我将drawBitmap中的offsetXY [[0]和[1]更改为它正确排列的那些值的负数。但是,原始位图绘制为纯黑色图像。 cl.ly/77e6b7839c1ffc94c1e0如何解决?
  • 不看代码就不确定。尝试检查源位图和目标位图的位深度。问题可能是您将 32 位图像(原始图像)绘制到 8 位图像(提取的 shadowImage)上。如果是这种情况,请在我有转换注释的地方执行 Bitmap shadowImage32 = shadowImage.copy(ARGB_8888, true) 之类的操作,然后绘制到那个人而不是 8 位 shadowImage 上。
  • 你好@Josh 我正在使用你的代码。它的工作,但我们怎样才能改变阴影颜色?
  • 用使用 ColorFilter 的 Paint 替换最后一个 drawBitmap 行中的 null。有关示例,请参见 stackoverflow.com/questions/3499095/…
  • Helin,您有更好的建议来在任意图像上创建投影吗?
【解决方案2】:

对于投影使用下面的代码

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

使用上面的drawable作为视图的背景

<View 
    android:id="@+id/divider" 
    android:background="@drawable/black_white_gradient"
    android:layout_width="match_parent" 
    android:layout_height="10sp"
    android:layout_below="@+id/buildingsList"/>

【讨论】:

  • 这并没有得到尽可能好的解释,但这并不是一个完全糟糕的方法。关键点在于,以渐变为背景的视图是一个单独的视图,应位于您希望阴影出现的视图的正下方。当要被遮蔽的视图占据屏幕的整个宽度时,这种方法效果最好,否则边角会看起来不对。
  • 这是一种用于声明性情况的方法,但在我的情况下,我根据读取的数据在代码中创建动态数量的按钮,因此对我的情况没有多大用处。
【解决方案3】:

这帮助我让影子工作,所以我想分享工作代码:

private Bitmap createShadowBitmap(Bitmap originalBitmap) {
    BlurMaskFilter blurFilter = new BlurMaskFilter(5, BlurMaskFilter.Blur.OUTER);
    Paint shadowPaint = new Paint();
    shadowPaint.setMaskFilter(blurFilter);

    int[] offsetXY = new int[2];
    Bitmap shadowImage = originalBitmap.extractAlpha(shadowPaint, offsetXY);

    /* Need to convert shadowImage from 8-bit to ARGB here. */
    Bitmap shadowImage32 = shadowImage.copy(Bitmap.Config.ARGB_8888, true);
    Canvas c = new Canvas(shadowImage32);
    c.drawBitmap(originalBitmap, -offsetXY[0], -offsetXY[1], null);

    return shadowImage32;
}

【讨论】:

  • 效果很好!
【解决方案4】:

对于 API 21(5.0)+ 添加 android:elevation="4dp"android:translationZ="4dp" 以查看说明。 Documentation

【讨论】:

    【解决方案5】:

    始终使用透明阴影,这样它们就可以粘在任何颜色上。

    shadow.xml

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

    在视图中

    <View 
        android:id="@+id/divider" 
        android:background="@drawable/shadow"
        android:layout_width="match_parent" 
        android:layout_height="5dp"/>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-23
      • 2012-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-08
      • 2011-05-22
      相关资源
      最近更新 更多