如何在 ImageView 中获取 Drawable 的尺寸? [复制]
Posted
技术标签:
【中文标题】如何在 ImageView 中获取 Drawable 的尺寸? [复制]【英文标题】:How to get the Dimensions of a Drawable in an ImageView? [duplicate] 【发布时间】:2011-06-06 16:09:02 【问题描述】:在 ImageView 中检索 Drawable 尺寸的最佳方法是什么?
我的ImageView
有一个初始化方法,我在其中创建ImageView
:
private void init()
coverImg = new ImageView(context);
coverImg.setScaleType(ScaleType.FIT_START);
coverImg.setImageDrawable(getResources().getDrawable(R.drawable.store_blind_cover));
addView(coverImg);
在布局或测量过程中的某个时刻,我需要 Drawable 的确切尺寸来调整它周围的其余组件。
coverImg.getHeight()
和coverImg.getMeasuredHeight()
不会返回我需要的结果,如果我使用coverImg.getDrawable().getBounds()
,我会在ImageView
缩放之前得到尺寸。
感谢您的帮助!
【问题讨论】:
【参考方案1】:刚刚试了一下,它对我有用:
int finalHeight, finalWidth;
final ImageView iv = (ImageView)findViewById(R.id.scaled_image);
final TextView tv = (TextView)findViewById(R.id.size_label);
ViewTreeObserver vto = iv.getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener()
public boolean onPreDraw()
// Remove after the first run so it doesn't fire forever
iv.getViewTreeObserver().removeOnPreDrawListener(this);
finalHeight = iv.getMeasuredHeight();
finalWidth = iv.getMeasuredWidth();
tv.setText("Height: " + finalHeight + " Width: " + finalWidth);
return true;
);
ViewTreeObserver
可让您在绘制布局之前监控布局(即所有内容都已测量),从这里您可以从 ImageView
获得缩放的测量结果。
【讨论】:
是的,它可以工作,但是在 oncreat() 加载之后还有其他方法可以让我们在 oncreat() 中获取高度或位置 我喜欢这个解决方案,它几乎可以满足我的需求。但由于某种原因,onPrewDraw 回调似乎永远不会停止触发。我只是记录了高度和宽度以确保。知道为什么吗? 覆盖视图的onsizeChanged()
方法。您无需添加预绘制侦听器。
@Kerry 仅当它是您自己编写的自定义视图时才有效。
onSizechanged()
无论是 View 还是开发者自定义 View 都会被调用。无论哪种方式,您仍然可以覆盖它,如果它不是自定义视图,只需调用超级。【参考方案2】:
在可绘制对象上调用 getIntrinsicHeight 和 getIntrinsicWidth。
public int getIntrinsicHeight ()
自:API 级别 1
返回底层可绘制对象的固有高度。 如果它没有固有高度(例如纯色),则返回 -1。
public int getIntrinsicWidth ()
自:API 级别 1
返回底层可绘制对象的固有宽度。
如果没有固有宽度,则返回 -1,例如纯色。
http://developer.android.com/reference/android/graphics/drawable/Drawable.html#getIntrinsicHeight()
这是原始drawable的大小。我想这就是你想要的。
【讨论】:
我也面临同样的问题。但是在不同尺寸的设备上,内在的高度和宽度是不同的,即使底层的 png 当然是相同的尺寸!这个怎么可能? “内在”的文档在哪里? 其实看Android的源码:这些内在值是受目标密度影响的,所以肯定不是图片的尺寸! 所以?那么获取图像尺寸的技巧是什么? @Zordid 你能不能做个参考,因为根据实验,这是原始图像的实际尺寸,换句话说,dp 单位的尺寸不是 px。 @Zordid 如果您将宽度为 120px 的图像存储在 xxhdpi 文件夹中,则 intristicWidth 在 xxhdpi 设备上将为 120,但在 hdpi 设备上将为 60。因为当然是自动缩放。【参考方案3】:对我来说获得可绘制尺寸的最可靠和最强大的方法是使用 BitmapFactory 来解码 Bitmap。它非常灵活 - 它可以解码来自可绘制资源、文件或其他不同来源的图像。
以下是使用 BitmapFactory 从可绘制资源中获取尺寸的方法:
BitmapFactory.Options o = new BitmapFactory.Options();
o.inTargetDensity = DisplayMetrics.DENSITY_DEFAULT;
Bitmap bmp = BitmapFactory.decodeResource(activity.getResources(),
R.drawable.sample_image, o);
int w = bmp.getWidth();
int h = bmp.getHeight();
如果您在 res 下使用多个密度可绘制文件夹,请务必小心,并确保您在 BitmapFactory.Options 中指定 inTargetDensity 以获得所需密度的可绘制对象。
【讨论】:
我采用了与内在值完全相同的值。 以 dp 为单位返回尺寸。 不适用于 svg 文件。叹息。【参考方案4】:获取Drawable的Width和Height的有效方法:
Drawable drawable = getResources().getDrawable(R.drawable.ic_home);
int width = drawable.getIntrinsicWidth();
int height = drawable.getIntrinsicHeight();
Log.i("Drawable dimension : W-H", width+"-"+height);
希望这会对你有所帮助。
【讨论】:
返回以像素为单位的尺寸,具体取决于底层 dpi 相关资产。【参考方案5】:这解决了我的问题。它在不真正加载整个图像的情况下解码图像边界的大小。
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
Bitmap bmp = BitmapFactory.decodeResource(this.getResources(), R.drawable.img , o);
int w = o.outWidth;
int h = o.outHeight;
【讨论】:
这个答案是 ubzack 的 answer 的劣质且语法不正确的副本。 @corsair992 感谢您的注意 :) 我刚刚发现我没有粘贴完整的代码。这就是为什么您觉得它是从其他人的答案中复制的:) 好的,但是您应该在decodeResource()
方法的最后一个参数之前添加一个逗号,以使其在语法上正确。
这是对noteme问题这一部分的最佳答案:“检索Drawable的尺寸”。它占用的资源较少:请参阅文档“在解码避免内存分配时将 inJustDecodeBounds 属性设置为 true”developer.android.com/training/displaying-bitmaps/…
它绝对不会占用大量资源,如果您想要调整图像大小的原因是因为您不想遇到 OutOfMemory 错误,那么这是一个重要的考虑因素。但是,它没有回答这个问题 - OP 希望知道在 ImageView 内缩放后可绘制对象的大小。我 +1 是希望它可能对登陆此页面的其他人有用,他们获得实际未缩放的可绘制对象的尺寸就足够了,但坦率地说,这不是正确的答案。以上是关于如何在 ImageView 中获取 Drawable 的尺寸? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
我需要从存储在我的 res/drawables 中的图像中将图像设置到我的 ImageView
如何在 ImageView 中获取 Drawable 的尺寸? [复制]