4

Im trying to find a way to measure an ImageView after an image has been loaded into it using Glide or Picasso (or anything really). Basically, im trying to layout other views on top of the image in certain positions, but need the final ImageViews dimensions to do so accurately.

Im not sure what the best layout to use to try and do this would be, but im currently using this:

<FrameLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
        <ImageView
            android:id="@+id/viewingImageView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    </FrameLayout>

and loading the image into viewingImageView. These are both inside a root FrameLayout as well but I dont think that matters.

This is my latest attempt, but as commented, using .getWidth() and .getHeight() on the ImageView return 0. The width/height of the resource returns the size of the original image.

Glide

.with(this)
.load(entry.getImageUrl())
.asBitmap()
.into(new SimpleTarget<Bitmap>() {
    @Override
    public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
        mImageView.setImageBitmap(resource);

        int width = mImageView.getMaxWidth(); //prints 0
        int height = mImageView.getMaxHeight(); //prints 0
        int resw = resource.getWidth(); //returns original image width
    }
});

So how can I get the image loaded and then measure the ImageView (or its wrapping FrameLayout) after the image has been loaded? Or if possible, measuring the dimensions of the finally laid out image would be better, as I know the image doesnt always fill the entire ImageView depending on scale types. I'm open to any solutions, the above is only what ive tried so far.

Marko
  • 20,385
  • 13
  • 48
  • 64
Orbit
  • 2,985
  • 9
  • 49
  • 106
  • `int height = mImageView.getMeasuredHeight();` `int width = mImageView.getMeasuredWidth();` – Hemanth Jan 04 '16 at 07:10
  • @Hemanth that returns 0 as well. – Orbit Jan 04 '16 at 07:13
  • Can you try and see this works? `mImageView.post(new Runnable() { @Override public void run() { int height = mImageView.getMeasuredHeight(); int width = mImageView.getMeasuredWidth(); } });` See [here](http://stackoverflow.com/a/27962342/2176708) – Hemanth Jan 04 '16 at 07:27
  • @Hemanth haha I had actually tried that, but I used a `postDelayed` and waited a second or two. This did get me the final size of the imageview, but is a bit odd of a solution as I need to overlay items asap instead of waiting a defined period of time. – Orbit Jan 04 '16 at 07:33
  • with `post`, you don't have to wait to get the size. `post(Runnable)` causes the runnable to be added to the message queue. The runnable will run on the UI thread. – Hemanth Jan 04 '16 at 07:36
  • @Hemanth I tried just `post` as well but it was returning 0. Probably because both Glide and Picasso load the images async. – Orbit Jan 04 '16 at 07:38
  • Are you getting the width and height using `post` after `mImageView.setImageBitmap(resource);`? – Hemanth Jan 04 '16 at 07:41
  • @Hemanth No, If I use `mImageView.post` right after `.setImageBitmap` it returns 0. If I use `postDelayed` and delay it for a couple seconds, I get a result. – Orbit Jan 04 '16 at 07:44

2 Answers2

6

You should wait for the view to be drawn, you can use OnGlobalLayoutListener like this

ViewTreeObserver vto = mImageView.getViewTreeObserver(); 
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 
    @Override 
    public void onGlobalLayout() { 
        this.mImageView.getViewTreeObserver().removeGlobalOnLayoutListener(this); 

        // Get the width and height
        int width  = mImageView.getMeasuredWidth();
        int height = mImageView.getMeasuredHeight(); 
    } 
});
Marko
  • 20,385
  • 13
  • 48
  • 64
  • Just came across this myself. This actually seems to work pretty good for getting the imageviews final dimensions. Do you have any idea how to get the final dimensions of the actual image after its drawn though? – Orbit Jan 04 '16 at 07:35
  • You would probably have to get the size of the Bitmap that is inside your ImageView, check [this](http://stackoverflow.com/questions/5888831/getting-pixels-from-bitmap-using-getpixels-illegalargumentexception) link here. – Marko Jan 04 '16 at 07:37
1

Create a custom class with image view. Use this onMeasure in the image view we can get the height and width

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

if (mNeedsInitialScale) { // Set by setImage when a new image is set
    // The measured width and height were set by super.onMeasure above
    setInitialScale(getMeasuredWidth(), getMeasuredHeight());
    mNeedsInitialScale = false;
}

}

Ramesh sambu
  • 3,577
  • 2
  • 24
  • 39
  • Im not exactly sure how to use this. What is `mNeedsInitialScale` and `setInitialScale`? – Orbit Jan 04 '16 at 07:41