自定义ImageView与投影

kco*_*ock 95 android overriding dropshadow imageview

好吧,我一直在阅读和搜索,现在我正在撞墙,试图解决这个问题.这是我到目前为止所拥有的:

package com.pockdroid.sandbox;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.widget.ImageView;

public class ShadowImageView extends ImageView {

private Rect mRect;
private Paint mPaint;

public ShadowImageView(Context context)
{
    super(context);
    mRect = new Rect();
    mPaint = new Paint();
    mPaint.setAntiAlias(true);
    mPaint.setShadowLayer(2f, 1f, 1f, Color.BLACK);
}

@Override
protected void onDraw(Canvas canvas) 
{
    Rect r = mRect;
    Paint paint = mPaint;

    canvas.drawRect(r, paint);
    super.onDraw(canvas);
}

@Override
protected void onMeasure(int w, int h)
{
    super.onMeasure(w,h);
    int mH, mW;
    mW = getSuggestedMinimumWidth() < getMeasuredWidth()? getMeasuredWidth() : getSuggestedMinimumWidth();
    mH = getSuggestedMinimumHeight() < getMeasuredHeight()? getMeasuredHeight() : getSuggestedMinimumHeight();
    setMeasuredDimension(mW + 5, mH + 5);
}
Run Code Online (Sandbox Code Playgroud)

}

测量中的"+5"是暂时的; 根据我的理解,我需要做一些数学运算来确定投影添加到画布的大小,对吧?

但是当我使用它时:

public View getView(int position, View convertView, ViewGroup parent) {
    ShadowImageView sImageView;
    if (convertView == null) {
        sImageView = new ShadowImageView(mContext);
        GridView.LayoutParams lp = new GridView.LayoutParams(85, 85);
        sImageView.setLayoutParams(lp);

        sImageView.setScaleType(ImageView.ScaleType.CENTER);
        sImageView.setPadding(5,5,5,5);
    } else {
        sImageView = (ShadowImageView) convertView;
    }

    sImageView.setImageBitmap(bitmapList.get(position));
    return sImageView;
}
Run Code Online (Sandbox Code Playgroud)

在我的ImageView中,当我运行程序时,我仍然只是一个正常的ImageView.

有什么想法吗?谢谢.

编辑:所以我在IRC频道中与RomainGuy进行了一些交谈,我现在正在使用以下代码处理普通矩形图像.它仍然不会直接将阴影绘制到我的位图的透明度,所以我仍然在努力.

@Override
protected void onDraw(Canvas canvas) 
{
    Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.omen);
    Paint paint = new Paint();
    paint.setAntiAlias(true);
    paint.setShadowLayer(5.5f, 6.0f, 6.0f, Color.BLACK);
    canvas.drawColor(Color.GRAY);
    canvas.drawRect(50, 50, 50 + bmp.getWidth(), 50 + bmp.getHeight(), paint);
    canvas.drawBitmap(bmp, 50, 50, null);       
}
Run Code Online (Sandbox Code Playgroud)

kco*_*ock 122

好吧,我没有预见到这个问题会有更多的答案,所以我现在最终选择的只是矩形图像的解决方案.我使用了以下NinePatch:

替代文字

以及XML中适当的填充:

<ImageView
        android:id="@+id/image_test"
        android:background="@drawable/drop_shadow"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingLeft="6px"
        android:paddingTop="4px"
        android:paddingRight="8px"
        android:paddingBottom="9px"
        android:src="@drawable/pic1"
        />
Run Code Online (Sandbox Code Playgroud)

得到一个相当不错的结果:

替代文字

不理想,但它会.

  • 不要忘记将png保存为drop_shadow.9.png. (17认同)
  • 可以在这里找到更多的分步教程:http://sapandiwakar.in/adding-shadows-to-views-in-android-using-9-patch-image/ (2认同)

Pau*_*rke 105

这取自Romain Guy在Devoxx的演讲,pdf在这里找到.

Paint mShadow = new Paint(); 
// radius=10, y-offset=2, color=black 
mShadow.setShadowLayer(10.0f, 0.0f, 2.0f, 0xFF000000); 
// in onDraw(Canvas) 
canvas.drawBitmap(bitmap, 0.0f, 0.0f, mShadow);
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助.

笔记

  1. 不要忘记Honeycomb及以上你需要调用 setLayerType(LAYER_TYPE_SOFTWARE, mShadow),否则你将看不到你的影子!(@Dmitriy_Boichenko)
  2. SetShadowLayer不幸的是,它不能用于硬件加速,因此它大大降低了性能(@Matt Wear)[1] [2]

  • 不要忘记Honeycomb及以上调用setLayerType(LAYER_TYPE_SOFTWARE,mShadow).如果没有,你将看不到你的影子. (14认同)
  • 遗憾的是,setShadowLayer无法使用硬件加速. (5认同)
  • Devoxx链接已经死了 (3认同)

Soy*_*oes 14

我相信UIFuel的回答

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

     <!-- Drop Shadow Stack -->
     <item>
        <shape>
            <padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
            <solid android:color="#00CCCCCC" />
        </shape>
    </item>
     <item>
        <shape>
            <padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
            <solid android:color="#10CCCCCC" />
        </shape>
    </item>
     <item>
        <shape>
            <padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
            <solid android:color="#20CCCCCC" />
        </shape>
    </item>
     <item>
        <shape>
            <padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
            <solid android:color="#30CCCCCC" />
        </shape>
    </item>
    <item>
        <shape>
            <padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
            <solid android:color="#50CCCCCC" />
        </shape>
    </item>

    <!-- Background -->
    <item>
    <shape>
            <solid android:color="@color/white" />
        <corners android:radius="3dp" />
    </shape>
    </item>
</layer-list>
Run Code Online (Sandbox Code Playgroud)


小智 11

我的脏解决方案:

private static Bitmap getDropShadow3(Bitmap bitmap) {

    if (bitmap==null) return null;
    int think = 6;
    int w = bitmap.getWidth();
    int h = bitmap.getHeight();

    int newW = w - (think);
    int newH = h - (think);

    Bitmap.Config conf = Bitmap.Config.ARGB_8888;
    Bitmap bmp = Bitmap.createBitmap(w, h, conf);
    Bitmap sbmp = Bitmap.createScaledBitmap(bitmap, newW, newH, false);

    Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    Canvas c = new Canvas(bmp);

    // Right
    Shader rshader = new LinearGradient(newW, 0, w, 0, Color.GRAY, Color.LTGRAY, Shader.TileMode.CLAMP);
    paint.setShader(rshader);
    c.drawRect(newW, think, w, newH, paint);

    // Bottom
    Shader bshader = new LinearGradient(0, newH, 0, h, Color.GRAY, Color.LTGRAY, Shader.TileMode.CLAMP);
    paint.setShader(bshader);
    c.drawRect(think, newH, newW  , h, paint);

    //Corner
    Shader cchader = new LinearGradient(0, newH, 0, h, Color.LTGRAY, Color.LTGRAY, Shader.TileMode.CLAMP);
    paint.setShader(cchader);
    c.drawRect(newW, newH, w  , h, paint);


    c.drawBitmap(sbmp, 0, 0, null);

    return bmp;
}
Run Code Online (Sandbox Code Playgroud)

结果: 在此输入图像描述


plu*_*ind 7

这个给你.在xml中静态设置ImageView的源代码或在代码中动态设置.

影子在这里是白色的.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content" android:layout_height="wrap_content">

    <View android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:background="@android:color/white" android:layout_alignLeft="@+id/image"
        android:layout_alignRight="@id/image" android:layout_alignTop="@id/image"
        android:layout_alignBottom="@id/image" android:layout_marginLeft="10dp"
        android:layout_marginBottom="10dp" />

    <ImageView android:id="@id/image" android:layout_width="wrap_content"
        android:layout_height="wrap_content" android:src="..."
        android:padding="5dp" />

</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)

  • @kcoppock - 没有必要低估这个答案 - 它并不是那么糟糕. (8认同)