1

Is it possible to do a drop shadow on the content of an ImageView?

Not a square, but an object drop shadow that acts on the non-transparent content of the ImageView.

Like this

nope
  • 751
  • 2
  • 12
  • 29
  • 1
    It is possible. You can use a layer list for this. All you need is your image view and an image of the drop. Then stack them as one using layer-list. – Thomas R. Aug 11 '15 at 06:39
  • @ThomasR. What do you mean by an image of the drop? I generate Bitmap's programmatically and can use them in ImageViews. I only have that so far. – nope Aug 11 '15 at 06:59
  • 1
    Ah ok. Then I think the answer by @King of Masses should help you. – Thomas R. Aug 11 '15 at 07:01

3 Answers3

0

This is taken from Romain Guy's presentation at Devoxx, pdf found here

As you already converted your image as a bitmap try like below

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);

Hope this helps.

For more information follow this answer

NOTES

  1. Don't forget for Honeycomb and above you need to invoke setLayerType(LAYER_TYPE_SOFTWARE, mShadow), otherwise you will not see your shadow!
  2. SetShadowLayer does not work with hardware acceleration unfortunately so it greatly reduces performances [1] [2]
Community
  • 1
  • 1
King of Masses
  • 18,405
  • 4
  • 60
  • 77
  • Tried [this](http://i.imgur.com/4SpkOnO.png) in my Custom Image View class but only shows the image. `@Override public void onDraw(Canvas canvas) { Bitmap piece = ((BitmapDrawable) this.getDrawable()).getBitmap(); Paint mShadow = new Paint(); mShadow.setShadowLayer(10.0f, 0.0f, 2.0f, 0xFF000000); this.setLayerType(LAYER_TYPE_SOFTWARE, mShadow); canvas.drawBitmap(piece, 0, 0, mShadow); }` – nope Aug 11 '15 at 07:10
  • you need to change the radios and offset values for better results – King of Masses Aug 11 '15 at 07:14
  • works better now but it does not show any color, shows the image's pixels as shadow layer. – nope Aug 11 '15 at 07:30
  • if my answer is helpful to resolve the issue then mark it as accepted, it may help some one in future :) – King of Masses Aug 11 '15 at 13:17
  • Sorry, I could not resolve the issue. Therefore I cannot mark it as accepted. I want to be able to set shadow color. – nope Aug 11 '15 at 13:19
  • mShadow.setShadowLayer(10.0f, 0.0f, 2.0f, 0xFF000000); here u can change this value to change your shadow color 0xFF000000 – King of Masses Aug 11 '15 at 13:20
0

I faced this same problem, and had to figure something out quick. This may not be the BEST solution, but my fix was to add

         android:adjustViewBounds="true"

on the image view, and then set the SAME image as the source as the background. That way the background is the same size and shape as the source image, and so the shadow looks natural, since shadows in android are based on the ui elements background.

ThePartyTurtle
  • 2,276
  • 2
  • 18
  • 32
0

Use this class to draw shadow on bitmap

public class ShadowGenerator {

    // Percent of actual icon size
    private static final float HALF_DISTANCE = 0.5f;
    public static final float BLUR_FACTOR = 0.5f/48;

    // Percent of actual icon size
    private static final float KEY_SHADOW_DISTANCE = 1f/48;
    public static final int KEY_SHADOW_ALPHA = 61;

    public static final int AMBIENT_SHADOW_ALPHA = 30;

    private static final Object LOCK = new Object();
    // Singleton object guarded by {@link #LOCK}
    private static ShadowGenerator sShadowGenerator;

    private  int mIconSize;

    private final Canvas mCanvas;
    private final Paint mBlurPaint;
    private final Paint mDrawPaint;
    private final Context mContext;

    private ShadowGenerator(Context context) {
        mContext = context;
        mCanvas = new Canvas();
        mBlurPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
        mBlurPaint.setMaskFilter(new BlurMaskFilter(mIconSize * BLUR_FACTOR, Blur.NORMAL));
        mDrawPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
    }

    public synchronized Bitmap recreateIcon(Bitmap icon) {
        mIconSize = Utils.convertDpToPixel(mContext,3)+icon.getWidth();
        int[] offset = new int[2];
        Bitmap shadow = icon.extractAlpha(mBlurPaint, offset);
        Bitmap result = Bitmap.createBitmap(mIconSize, mIconSize, Config.ARGB_8888);
        mCanvas.setBitmap(result);

        // Draw ambient shadow
        mDrawPaint.setAlpha(AMBIENT_SHADOW_ALPHA);
        mCanvas.drawBitmap(shadow, offset[0], offset[1], mDrawPaint);

        // Draw key shadow
        mDrawPaint.setAlpha(KEY_SHADOW_ALPHA);
        mCanvas.drawBitmap(shadow, offset[0], offset[1] + KEY_SHADOW_DISTANCE * mIconSize, mDrawPaint);

        // Draw the icon
        mDrawPaint.setAlpha(255);
        mCanvas.drawBitmap(icon, 0, 0, mDrawPaint);

        mCanvas.setBitmap(null);
        return result;
    }



    public static ShadowGenerator getInstance(Context context) {

        synchronized (LOCK) {
            if (sShadowGenerator == null) {
                sShadowGenerator = new ShadowGenerator(context);
            }
        }
        return sShadowGenerator;
    }

}
Ali Imran
  • 8,927
  • 3
  • 39
  • 50