How to get the width and height of an android.widget.ImageView?
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
Getting the width and height of an ImageView in Android is a common task for dynamic layouts, image scaling, and animations. The challenge is that view dimensions are not available until Android completes its measure and layout passes. Calling getWidth() or getHeight() too early, such as in onCreate() or onCreateView(), returns zero. This article covers the correct timing and APIs for reliably retrieving view dimensions.
Why Dimensions Are Zero in onCreate
Android views go through three phases before they appear on screen: measure, layout, and draw. In onCreate(), none of these phases have completed, so every view reports a width and height of zero.
This behavior is consistent across all view types, not just ImageView. You need to defer the measurement until after the layout pass completes.
Using View.post
The simplest approach is View.post(), which queues a Runnable on the view's message queue. By the time it executes, the view has been measured and laid out.
This works reliably in most cases. The Runnable executes after the current layout pass, so dimensions are available. However, if the view is not yet attached to the window, post may not execute.
Using doOnLayout (AndroidX)
The AndroidX Core KTX library provides doOnLayout, which is a more explicit and reliable callback. It fires exactly once after the next layout pass.
If the view has already been laid out, doOnLayout fires immediately. This eliminates a common race condition where the callback is registered after layout has already completed.
For cases where you need to react to every layout change (for example, during animations or orientation changes), use addOnLayoutChangeListener instead.
Using ViewTreeObserver
Before AndroidX KTX, the standard approach was ViewTreeObserver.OnGlobalLayoutListener. This fires when the global layout state changes.
This approach works in Java projects or when AndroidX KTX is not available. Always remove the listener after the first invocation to prevent it from firing on every layout change, which wastes CPU and can cause infinite loops if the callback itself triggers a layout.
View Size vs Intrinsic Image Size
There is an important distinction between the ImageView dimensions and the underlying image dimensions. The ImageView size depends on layout parameters (match_parent, wrap_content, fixed dp), while the intrinsic size is the actual pixel dimensions of the image resource or downloaded bitmap.
For a 1920x1080 image displayed in a 200x200 dp ImageView, the view dimensions reflect the layout size while the intrinsic dimensions report the original image resolution. The scaleType attribute (centerCrop, fitCenter, etc.) controls how the image maps into the view bounds but does not change either measurement.
Getting Dimensions in Java
The same approaches work in Java with slightly different syntax.
For the ViewTreeObserver approach in Java, the pattern is identical to the Kotlin version shown above, using an anonymous inner class.
Handling Dynamic Image Loading
When loading images asynchronously with libraries like Glide or Coil, the ImageView may have dimensions from the layout pass, but the drawable might not be set yet.
Using CustomTarget (Glide) or an image request listener (Coil) gives you access to the drawable dimensions at the moment the image is ready.
Common Pitfalls
- Reading width/height in onCreate or onCreateView always returns zero because the measure and layout passes have not run yet.
- Forgetting to remove the OnGlobalLayoutListener causes the callback to fire on every layout change, leading to performance issues or infinite layout loops.
- Confusing view size with image intrinsic size leads to incorrect scaling calculations; the view size comes from layout params while intrinsic size is the original image resolution.
- Using View.post on a detached view means the runnable may never execute; prefer
doOnLayoutwhich handles this case by firing immediately if layout already happened. - Not accounting for padding and margins when calculating usable image area; use
imageView.paddingLeft,paddingRight, etc., to get the actual content area within the view bounds.
Summary
- View dimensions are only available after the measure and layout passes; never read them in
onCreate(). - Use
doOnLayoutfrom AndroidX Core KTX as the preferred one-shot callback for getting dimensions after layout. - Use
View.postas a simpler alternative that works in most cases by deferring execution until after the current layout pass. - Distinguish between view dimensions (
getWidth()/getHeight()) and image dimensions (drawable.intrinsicWidth/intrinsicHeight) for correct scaling logic. - Always remove
ViewTreeObserver.OnGlobalLayoutListenerafter first use to prevent repeated and unnecessary callback invocations.
Related reading
- How to get TimeZone from android mobile?
- How to get UILabel to respond to tap?
- How to get UITableView from UITableViewCell?
- How to get UITableViewCell indexPath from the Cell?
- How to go back to previous page if back button is pressed in WebView?
- How to group by the elements of an array in Swift
- How to group by the elements of an array in Swift
- How to handle button clicks using the XML onClick within Fragments
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.