it-swarm.com.de

ImageView adjustViewBounds funktioniert nicht

Ich habe eine ImageView mit Android:layout_width=100dp, Android:layout_height=wrap_content und Android:adjustViewBounds=true

Die Quelle ist ein 50 x 50 px Bild. Das Seitenverhältnis wird jedoch nicht beibehalten - die Höhe des ImageView-Objekts beträgt 50px, nicht 100px (d. H. adjustViewBounds funktioniert nicht). Wenn ich ein 200x200px-Bild habe, funktioniert es - Breite und Höhe sind 100px. Dieser Code ergibt ein 100px breites und 50px großes Bild, aber das src-Bild ist quadratisch:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="fill_parent"
    Android:layout_height="fill_parent">

    <ImageView
        Android:id="@+id/photo"
        Android:src="@drawable/icon"
        Android:layout_width="100dp"
        Android:layout_height="wrap_content"
        Android:scaleType="fitXY"
        Android:adjustViewBounds="true" />

</LinearLayout>
36
fhucho

Das Problem ist, dass adjustViewBoundsdie Größe der ImageView nicht über die natürlichen Abmessungen der Zeichenfläche hinaus vergrößert. Die Ansicht wird nur verkleinert, um das Seitenverhältnis beizubehalten. Wenn Sie ein 500x500-Image anstelle eines 50x50-Images bereitstellen, sollte dies funktionieren.

Wenn Sie sich für die Stelle interessieren, an der dieses Verhalten implementiert ist, lesen Sie die OnMeasure-Implementierung von ImageView.Java .

Eine Problemumgehung besteht darin, eine benutzerdefinierte ImageView zu implementieren, die dieses Verhalten in onMeasure ändert.

65
Roman Nurik

Es gibt einen einfacheren Weg. Machen Sie Ihre ImageView so:

<ImageView
  Android:layout_width="match_parent"
  Android:layout_height="match_parent"
  Android:scaleType="fitCenter"
  Android:adjustViewBounds="true"/>

Auf diese Weise wird drawable gedehnt, um in ImageView Center zu passen, indem das Seitenverhältnis Beibehalten wird. Wir müssen nur die richtige Höhe berechnen, um sie proportional zu machen So haben wir kein Leerzeichen:

private void setImageBitmap(Bitmap bitmap, ImageView imageView){
    float i = ((float)imageWidth)/((float)bitmap.getWidth());
    float imageHeight = i * (bitmap.getHeight());
    imageView.setLayoutParams(new RelativeLayout.LayoutParams(imageWidth, (int) imageHeight));
    imageView.setImageBitmap(bitmap);
}
11
vladexologija

Neben @ RomanNurik Antwort

Sie finden die Arbeitslösung hier , entweder den Code zum Einfügen oder Einfügen der Gradle-Abhängigkeit

dependencies {
    compile 'com.inthecheesefactory.thecheeselibrary:adjustable-imageview:1.0.1'
}

P.S. Die von @Nilzor bereitgestellte Lösung hat für mich nicht funktioniert

2
duviteck

Ich hatte eine ähnliche Anforderung. In meinem Fall wollte ich, dass das Bild quadratisch ist, und dass ImageView dem Seitenverhältnis entspricht, damit ich den Hintergrund und die Auffüllung verwenden kann, um einen Rand zu zeichnen.

Ich habe die Antworten hier gelesen, aber anstatt ImageView zu überschreiben, entschied ich mich, ein Layout zu erstellen, das garantiert, dass der Inhalt (sollte nur eine Ansicht sein) quadratisch sein. Auf diese Weise könnte ich eine Standard-ImageView verwenden. (Und Sie wissen nie, ich möchte später vielleicht etwas anderes machen. Obwohl wahrscheinlich nicht.)

Falls es für alle anderen nützlich ist, hier der Code (kopieren Sie gerne). Es gibt wahrscheinlich Fehler, da ich es einfach für meine App funktionierte und dann aufhörte. :)

public class SquareLayout extends ViewGroup
{
    public SquareLayout(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
    }

    public SquareLayout(Context context, AttributeSet attrs)
    {
        super(context, attrs);
    }

    public SquareLayout(Context context)
    {
        super(context);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b)
    {
        // Work out width and height, and square size.
        int width = r - l;
        int height = b - t;

        int size, xOffset, yOffset;
        if(width < height)
        {
            size = width;
            xOffset = 0;
            yOffset = (height - size) / 2;
        }
        else
        {
            size = height;
            xOffset = (width - size) / 2;
            yOffset = 0;
        }

        for(int i = 0; i < getChildCount(); i++)
        {
            View child = getChildAt(i);
            child.layout(xOffset, yOffset, size + xOffset, size + yOffset);
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        // Get width and height.
        int w = -1, h = -1;
        switch(MeasureSpec.getMode(widthMeasureSpec))
        {
        case MeasureSpec.AT_MOST:
        case MeasureSpec.EXACTLY:
            w = MeasureSpec.getSize(widthMeasureSpec);
            break;

        case MeasureSpec.UNSPECIFIED:
            break;
        }
        switch(MeasureSpec.getMode(heightMeasureSpec))
        {
        case MeasureSpec.AT_MOST:
        case MeasureSpec.EXACTLY:
            h = MeasureSpec.getSize(heightMeasureSpec);
            break;

        case MeasureSpec.UNSPECIFIED:
            break;
        }

        // If only one of width/height is unspecified, set them both the same.
        if(w == -1 && h != -1)
        {
            w = h;
        }
        else if(h == -1 && w != -1)
        {
            h = w;
        }

        // Either they're both specified or both unspecified.
        int childMeasureSpec;
        if(w == -1)
        {
            childMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
        }
        else
        {
            childMeasureSpec = MeasureSpec.makeMeasureSpec(w, MeasureSpec.EXACTLY);
        }

        // Pass through to children.
        int maxDimension = 1;
        for(int i = 0; i < getChildCount(); i++)
        {
            View child = getChildAt(i);
            child.measure(childMeasureSpec, childMeasureSpec);
            maxDimension = Math.max(maxDimension, child.getMeasuredWidth());
            maxDimension = Math.max(maxDimension, child.getMeasuredHeight());
        }

        if(w == -1)
        {
            w = maxDimension;
            h = maxDimension;
        }

        setMeasuredDimension(w, h);
    }
}
0
sam