Okay, I've been reading and searching around, and am now banging my head against the wall trying to figure this out. Here's what I have so far:
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); }
}
The "+5" in the measurements are there as temporary; From what I understand I'll need to do some math to determine the size that the drop shadow adds to the canvas, right?
But when I use this:
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; }
in my ImageView, I still get just a normal ImageView when I run the program.
Any thoughts? Thanks.
EDIT: So I spoke with RomainGuy some in the IRC channel, and I have it working now for plain rectangular images with the below code. It still won't draw the shadow directly to my bitmap's transparency though, so I'm still working on that.
@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); }
Basically, it works like a stack where each view is stacked on top of the other. Create a drawable file for shadow view and assign the name image_shadow and add the below code in this file. Now, open the XML file and add the below code into it, and set this drawable file as view background. That's it.
To set the default (resting) elevation of a view, use the android:elevation attribute in the XML layout. To set the elevation of a view in the code of an activity, use the View. setElevation() method.
Elevation (Android) Elevation is the relative depth, or distance, between two surfaces along the z-axis. Specifications: Elevation is measured in the same units as the x and y axes, typically in density-independent pixels (dp).
Okay, I don't foresee any more answers on this one, so what I ended up going with for now is just a solution for rectangular images. I've used the following NinePatch:
along with the appropriate padding in 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" />
to get a fairly good result:
Not ideal, but it'll do.
This is taken from Romain Guy's presentation at Devoxx, pdf found here.
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.
NOTES
setLayerType(LAYER_TYPE_SOFTWARE, mShadow)
, otherwise you will not see your shadow! (@Dmitriy_Boichenko)SetShadowLayer
does not work with hardware acceleration unfortunately so it greatly reduces performances (@Matt Wear) [1] [2] If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With