ImageView width incorrectly scaled on Nexus 4?

609 views Asked by At

I'm using the technique described here. The following line works on all my devices, except my Nexus 4:

int imageWidth = horizontalScrollView.getChildAt(0).getMeasuredWidth();

The layout is simple:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <HorizontalScrollView
        android:id="@+id/main_scroller"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <ImageView
            android:id="@+id/main_image"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:adjustViewBounds="true"
            android:scaleType="centerCrop" />
    </HorizontalScrollView>
</RelativeLayout>

Into this HorizontalScrollView I programmatically create a bitmap that is around 500x1000 pixels. Hence, the image will be stretched to fill roughly 1200x2400 (see centerCrop). Thus, the width of the ImageView should be 2400. And it is! On my Nexus 7, Samsung S3 Mini and some other low-density devices. But not on my Nexus 4! On Nexus 4, it does indeed have its height stretched but not the width (yeah, unbelievable): 1000x1000 pixels. I've tried both getWidth() and getMeasuredWidth(). And when I try to scroll it, I can see only 50% of the image horizontally (but 100% vertically).

UPDATE 1:

Looking at mDrawMatrix of my ImageView, I can see that it differs:

Nexus 7: Matrix{[2.2979167, 0.0, 0.0][0.0, 2.2979167, 0.0][0.0, 0.0, 1.0]}

Nexus 4: Matrix{[2.1458333, 0.0, -623.0][0.0, 2.1458333, 0.0][0.0, 0.0, 1.0]}

UPDATE 2:

This is a bug in ImageView.onMeasure() in Android 4.2.2, fixed in 4.3. The question now is, how do I add this fix in 4.2.2? Overriding onMeasure() is not 100% trivial since a lot of private functions are being called.

1

There are 1 answers

0
Ben Clayton On

I've had the same issue on Samsung Galaxy S4 4.2.2 and S3 4.1.1, whatever I did, a programmatically-set Bitmap would not scale to fill the width of it's parent ViewGroup. I tried all combinations of scaleType to no avail.

For me the solution was to set set the density on the bitmap to a specific value before displaying it.

        Bitmap myBitmap = ... 

        // S3 and S4 get confused about displaying bitmaps without a specific density,
        // and fail to scale them properly. Setting the density to this value helps (is possible ANY density helps, but haven't tested this)
        myBitmap.setDensity(DisplayMetrics.DENSITY_HIGH);

        myImageView.setImageBitmap(myBitmap);