更新:
多设备屏幕尺寸是一个红鲱鱼 - 问题只是图像无法正确放大以填充屏幕 - 请参阅对 Ivan 答案的评论。
我有一个包含一张图像的布局文件:
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/image"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="centerCrop" />
然后我分配一个可绘制的,它很小并且必须放大:
setContentView(R.layout.image_story);
ImageView image = (ImageView)findViewById(R.id.image);
image.setImageDrawable(s.image);
以下是它在具有不同屏幕尺寸的两个 AVD 上渲染的方式。这些应该是相同的(详细问题在底部)。抱歉图片较大。
使用scaleType = centerCrop:

与 centerInside

AVD:

编辑:
使用layout_height="fill_parent" 和scaleType="centerInside"

我有一个具有默认值的 2.1 AVD,因此屏幕较小,这完全符合预期 - 图像是放大以填充宽度,并且视图高度将覆盖到缩放后的高度。
在我的具有较长屏幕的 Droid Bionic 以及具有相同屏幕尺寸的任何 AVD 上,这不起作用 - 图像会缩放以填充宽度,但视图会包裹到原始预置-缩放图像高度,因此顶部和底部被裁剪掉。
我不知道为什么设备屏幕宽高比会对此产生影响。我尝试了无数种布局参数和比例类型的组合,试图让它在 Bionic 上工作。在较小的屏幕上,一切都完全按照预期运行,而在较大的屏幕上则不然。如果我在 dp 中显式设置图像高度,它会按预期工作,但我永远不知道图像(或屏幕)的尺寸是多少。有什么建议吗?
Update:
The multiple device screen dimensions is a red herring - the problem is just that the image does not scale up properly to fill the screen - see comments on Ivan's answer.
I have a layout file with one image:
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/image"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="centerCrop" />
Then I assign a drawable, which is small and must be scaled up:
setContentView(R.layout.image_story);
ImageView image = (ImageView)findViewById(R.id.image);
image.setImageDrawable(s.image);
Here is how it is rendered on two AVDs with different screen dimensions. These should be the same (detailed question at the bottom). Sorry for the large images.
with scaleType=centerCrop:


with centerInside


AVDs:


Edit:
With layout_height="fill_parent" and scaleType="centerInside"


I have a 2.1 AVD with the default values, so the screen is smaller, and this works exactly as expected- the image is scaled up to fill the width, and the view height is wrapped to the scaled height.
On my Droid Bionic with a longer screen, and on any AVD with the same screen dimensions, this doesn't work- the image is scaled to fill the width, but the view is wrapped to the original pre-scale image height, so the top and bottom are cropped off.
I have no idea why the device screen aspect ratio would have an effect on this. I've tried countless combination of layout parameters and scale types trying to get this to work on the Bionic. Everything works exactly as expected on the smaller screen, and not on the larger. If I set the image height explicitly in dp
, it works as expected, but I never know what the dimensions of the image (or screen) will be. Any suggestions?
发布评论
评论(2)
这确实是一个非常好的问题。
这就是它表现得这样的原因(来自 ImageView.onMeasure(int, int) [line 661]):
它的作用是调整仅当基于可绘制对象的宽高比的新高度和调整后的宽度(在我们的例子中,即父视图的确切宽度)小于调整后的高度(此时在我们的例子中,点只是可绘制的原始高度加上填充,如果您希望我进一步缩小这一点,请告诉我。)
我不明白的是为什么存在新高度必须更小的限制。仅当我们的 heightSize 为 EXACTLY 或 AT_MOST 并且已设置为上限时才有意义。在其他情况下,没有必要这样做。
所以实际上,而不是整个 661 到 663 应该有另一个调用来
确保我们只在应该限制的时候使用高度限制(即,我们在 heightSpec 中得到了 AT_MOST 限制,并且 heightSpec 中的高度值小于除非我们使用可变宽度,否则这里不可能发生新的高度。)
也许,我错过了一些东西。伙计们,无论谁正在阅读本文,如果您发现任何缺陷,请发表评论,特别是如果您是 Google Android 团队的一员:)
PS 作为一种解决方法,我可以建议您实现自定义 ImageView 并覆盖 onMeasure(int, int) 以将边界设置为您的确切宽高比。如果您需要有关实际代码的帮助,请告诉我。
UPD 我要写下名字来吸引 Google 聪明的 Android 人员的注意(我希望这些人已经设置了 Google 快讯):Romain Guy、Roman Nurik、Reto Meier,拜托,看看这个讨论。
That is a very good question indeed.
Here's the reason it's behaving like that (from ImageView.onMeasure(int, int) [line 661]):
What it does is it adjusts the height of the view only if the new height that is based on aspect ratio of the drawable and the adjusted width (in our case, that's exact width of the parent view) is smaller than the adjusted height (which at this poin is just drawable's native height plus padding in our case. Let me know if you want me to brake down this point further.)
What I don't get is why is there the restriction that new height must be smaller. It makes sense only if our heightSize is either EXACTLY or AT_MOST and has been set to the upper bound. In other cases it's not necessary for it to be so.
So actually instead of the whole piece 661 through 663 there should have been another call to
to make sure we only use the height restriction when it should be restricted (ie. we got AT_MOST restriction in heightSpec and the height value in heightSpec is smaller than the new height. EXACTLY can't happen here unless we use variable width.)
Maybe, I missed something there. Guys, whoever is reading this, please comment if you see any flaws in that, especially if you're part of Android team at Google :)
PS As a workaround, I can suggest you implement a custom ImageView and override onMeasure(int, int) to set the bounds to your exact aspect ratio. Let me know if you need help on the actual code.
UPD I'm going to write out names to catch attention of smart android guys at Google (I'm hoping the guys have Google Alerts set up): Romain Guy, Roman Nurik, Reto Meier, please, take a look at this discussion.
据我了解,您需要缩放图像以保持其纵横比。
scaleType="fitCenter"
应该为您提供所需的行为:如果没有帮助,请尝试将其添加到清单文件中:
As I understand, you need to scale the image maintaining its aspect ratio.
scaleType="fitCenter"
should give you the desired behavior:If it doesn't help, try adding this to the manifest file: