Android 如何在保持纵横比的同时使图像尽可能大

Android 如何在保持纵横比的同时使图像尽可能大,android,android-layout,imageview,Android,Android Layout,Imageview,我有一个图像,它比我希望它适合里面的容器小。我希望图像拉伸,保持它的纵横比,使其尽可能大 为了说明这个问题: <ImageView android:layout_width="match_parent" android:layout_height="wrap_content" android:src="@drawable/thumbnail" android:scaleType="fitXY"

我有一个图像,它比我希望它适合里面的容器小。我希望图像拉伸,保持它的纵横比,使其尽可能大

为了说明这个问题:

<ImageView  android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:src="@drawable/thumbnail"
            android:scaleType="fitXY"
            android:adjustViewBounds="true"/>
编辑

给定的
scaleType=“fitCenter”
图像视图将准确地扩展/缩小其内部的
@drawable
,使其尽可能大,同时保持其纵横比


在以任何方式缩放
@drawable
之前,先定义
图像视图的尺寸。
ImageView
尺寸不受其所包含的缩放的影响
@drawable

看起来您需要fitCenter,它使用。

XML

XML中解决此问题的唯一方法是尽可能使用
“匹配父项”
或离散最大值,而不是
“包装内容”
。这将确保
ImageView
的大小正确,这意味着添加
scaleType=“fitCenter”
将确保
@drawable
的缩放正确

以编程方式

这很难看,但您可以在为ImageView的尺寸指定离散值后调整其大小:

    final ImageView thumbnailView = (ImageView) toReturn.findViewById(R.id.thumbnail);  

    ViewTreeObserver thumbnailViewVto = thumbnailView.getViewTreeObserver();
    thumbnailViewVto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
        private boolean changed = false;
        @Override
        public void onGlobalLayout() {
            if(!changed) {
                Drawable image = getResources().getDrawable(R.drawable.thumbnail);
                float heighToWidthRatio = image.getIntrinsicWidth()/image.getIntrinsicHeight();
                int height = thumbnailView.getHeight();

                thumbnailView.setLayoutParams(
                        new LayoutParams(
                                (int) (height * heighToWidthRatio), height));
                changed = true;
            }
        }
    });
编辑

    final ImageView thumbnailView = (ImageView) toReturn.findViewById(R.id.thumbnail);  

    thumbnailView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

        @Override
        public void onGlobalLayout() {
            // Remove the GlobalOnLayout Listener so it only fires once.
            thumbnailView.getViewTreeObserver().removeGlobalOnLayoutListener(this)

            // Find the images Height to Width ratio
            Drawable image = getResources().getDrawable(R.drawable.thumbnail);
            float heighToWidthRatio = image.getIntrinsicWidth()/image.getIntrinsicHeight();

            // Use this ratio to discover the ratio of the ImageView to allow it to perfectly contain the image.
            int height = thumbnailView.getHeight();
            thumbnailView.setLayoutParams(new LayoutParams(
                                (int) (height * heighToWidthRatio), height));
        }
    });

这是纵横比,但图像不再填充。如果ImageView的高度是正确的,这可以通过编程实现,但我希望通过XML实现。@Graeme-来自链接:“计算一个可以保持原始src纵横比的比例,但也可以确保src完全适合dst。至少有一个轴(X或Y)结果在dst内居中。”-他们的描述似乎暗示图像将被拉伸以填充宽度或高度。也许它只是缩小以适应,而不是拉伸以适应?这一描述完全正确-因为其中一个维度设置为“包裹内容”,但是ImageView的大小初始化似乎发生在缩放之前,因此视图的高度已经设置,并且它使用最小的轴来适应,而没有放大。对我来说,这是一个常见的问题,我从来没有找到一个干净的解决方案。为一个帧添加一个背景9-patch,尝试修复会更糟糕。我很确定这是你必须通过编程来完成的事情,但是如果有人能解决这个问题,那就太好了。+1对于一个完整描述的问题,布尔
改变了
是为了什么?这样onGlobalLayout侦听器就不会重复启动。随着年龄的增长和智慧的提高,我现在只需将
OnGlobalLayoutListener
ViewTreeObserver
中删除,作为
onGlobalLayout()
方法中的第一个操作。(有关详细信息,请参见我的编辑)
    final ImageView thumbnailView = (ImageView) toReturn.findViewById(R.id.thumbnail);  

    thumbnailView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

        @Override
        public void onGlobalLayout() {
            // Remove the GlobalOnLayout Listener so it only fires once.
            thumbnailView.getViewTreeObserver().removeGlobalOnLayoutListener(this)

            // Find the images Height to Width ratio
            Drawable image = getResources().getDrawable(R.drawable.thumbnail);
            float heighToWidthRatio = image.getIntrinsicWidth()/image.getIntrinsicHeight();

            // Use this ratio to discover the ratio of the ImageView to allow it to perfectly contain the image.
            int height = thumbnailView.getHeight();
            thumbnailView.setLayoutParams(new LayoutParams(
                                (int) (height * heighToWidthRatio), height));
        }
    });