How Flutter handles images and asset density and scaling differently than Android’s legacy drawable-*dpi folders? Let’s break it down clearly 👇
🧩 1. How Flutter handles multiple resolutions
Flutter doesn’t use the drawable-mdpi, drawable-hdpi, etc. system directly.
Instead, it uses device pixel ratios (DPR) and asset variants.
You can define image variants like this:
assets/
images/
icon.png ← base image (1.0x)
2.0x/icon.png ← for DPR 2.0 (e.g. Retina, xxhdpi)
3.0x/icon.png ← for DPR 3.0 (xxxhdpi)
And in your pubspec.yaml:
flutter:
assets:
- assets/images/icon.png
Flutter automatically detects and uses the correct resolution image for:
- ✅ Android (
drawable-*dpi) - ✅ iOS (Retina)
- ✅ Web
- ✅ Windows
- ✅ macOS
- ✅ Linux
It’s completely cross-platform — Flutter’s rendering engine does the scaling.
🧠 2. How it works behind the scenes
- When your app runs, Flutter reads the device’s
MediaQuery.devicePixelRatio(e.g. 1.0, 2.0, 3.0). - It then chooses the closest matching variant (
1.0x,2.0x,3.0x) automatically. - You only need to declare the base asset path in
pubspec.yaml.
📐 3. Example structure mapping
| Android density | Typical devicePixelRatio | Flutter folder |
|---|---|---|
| mdpi | 1.0x | assets/images/ |
| hdpi | 1.5x | assets/images/1.5x/ |
| xhdpi | 2.0x | assets/images/2.0x/ |
| xxhdpi | 3.0x | assets/images/3.0x/ |
| xxxhdpi | 4.0x | assets/images/4.0x/ |
🧰 4. Bonus: Vector assets
If you want fully scalable cross-platform graphics, use:
.svgwithflutter_svg.flr(Rive) animations.json(Lottie)
These scale perfectly on all platforms, removing the need for bitmap variants.
✅ TL;DR
| Goal | Solution |
|---|---|
| Use multiple density bitmaps | Put them in 1.0x/, 2.0x/, 3.0x/ subfolders |
| Work across Android/iOS/Web/Desktop | ✅ Flutter does it automatically |
| Prefer full scalability | Use SVG or Lottie |
