带阴影的自定义 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);
}
}
测量中的“+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;
}
在我的 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);
}
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);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
好吧,我预计不会有更多关于这个问题的答案,所以我现在最终选择的只是矩形图像的解决方案。我使用了以下 NinePatch:
以及 XML 中的适当填充:
以获得相当好的结果:
不理想,但也可以。
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:
to get a fairly good result:
Not ideal, but it'll do.
本文摘自 Romain Guy 在 Devoxx 上的演讲,pdf 格式可在此处找到。
注释
setLayerType(LAYER_TYPE_SOFTWARE, mShadow)
,否则你将看不到自己的影子! (@Dmitriy_Boichenko)SetShadowLayer
确实不幸的是,不能与硬件加速一起使用,所以它很大
降低性能 (@Matt Wear) [1] [2]
This is taken from Romain Guy's presentation at Devoxx, pdf found here.
NOTES
setLayerType(LAYER_TYPE_SOFTWARE, mShadow)
, otherwise you will not see your shadow! (@Dmitriy_Boichenko)SetShadowLayer
doesnot work with hardware acceleration unfortunately so it greatly
reduces performances (@Matt Wear) [1] [2]
我相信这个答案来自 UIFuel
I believe this answer from UIFuel
我的肮脏解决方案:
结果:

My dirty solution:
result:

给你。在 xml 中静态设置 ImageView 的源,或在代码中动态设置 ImageView 的源。
这里的阴影是白色的。
Here you are. Set source of ImageView statically in xml or dynamically in code.
Shadow is here white.
我设法使用此代码应用渐变边框。
I manage to apply gradient border using this code..
这对我有用......
This works for me ...
这里是 Paul Burke 答案的实现:
TODO:
仅当 API 级别 > 时才执行 setLayerType(LAYER_TYPE_SOFTWARE, mShadow); 10
Here the Implementation of Paul Burkes answer:
TODO:
execute
setLayerType(LAYER_TYPE_SOFTWARE, mShadow);
only if API Level is > 10我基于上面的答案 - https://stackoverflow.com/a/11155031/2060486 - 创建一个所有侧面周围的阴影..
根据需要更改 const 中的颜色。
I've built upon the answer above - https://stackoverflow.com/a/11155031/2060486 - to create a shadow around ALL sides..
Change the color in the const as you see fit.
使用此类在位图上绘制阴影
Use this class to draw shadow on bitmaps
如果你想使用自定义imageView,我建议你使用这个
视图看起来很完美,并且不使用任何九路径图像
If you want to use the custom imageView, I suggest you use this one
View look perfect and dont't use any nine path image