Choosing a libGdx Viewport: FitViewport vs ExtendViewport vs ScreenViewport
A decision guide to libGdx viewports: when FitViewport's letterboxing beats ExtendViewport's extra visible world, when ScreenViewport makes sense for UI, and how to implement and validate your choice.
06 May 2026, 09:57 UTC

The decision you have to make
Every libGdx game renders into a virtual coordinate system, but phones, tablets, and desktop windows come in wildly different aspect ratios. The Viewport classes in com.badlogic.gdx.utils.viewport decide how your virtual world maps onto physical pixels. Picking the wrong one early means either distorted art, unwanted letterbox bars, or players on wider phones seeing more of the level than you intended.
The useful takeaway: for most 2D games the real choice is between FitViewport (constant visible world, black bars) and ExtendViewport (no bars, wider screens see more world). The others are niche tools.
What each supported option does
All viewports are constructed with a virtual world size (for example 800x480 units) and a camera. On resize they compute a transform so your drawing code never changes.
| Viewport | Aspect ratio | Visible world | Side effect | Best for |
|---|---|---|---|---|
FitViewport | Preserved | Constant | Letterbox bars | Games where every player must see exactly the same area |
ExtendViewport | Preserved | Grows on wider/taller screens | None (fills screen) | Most 2D gameplay; UI anchored to edges |
ScreenViewport | Matches device | 1:1 with pixels | UI size varies by DPI | Pixel-perfect HUDs, menus |
StretchViewport | Not preserved | Constant | Distortion | Rarely acceptable; quick prototypes |
FillViewport | Preserved | Constant; crops overflow | Edges of the world cut off | Backgrounds where cropping is safe |
Trade-offs that actually matter
Fairness vs. fill. FitViewport guarantees a level designer's framing is identical on a 4:3 tablet and a 20:9 phone, at the cost of black bars. ExtendViewport fills the whole screen but rewards players with wider displays — a real concern in competitive or precision-platforming games.
UI vs. world. A common, well-supported pattern is two viewports: an ExtendViewport for the game world and a ScreenViewport (or a second FitViewport) for a Stage-based HUD. Scene2D's Stage accepts a viewport in its constructor, which makes this split straightforward.
World units. With ScreenViewport your units are pixels, so a 48-unit button is tiny on a high-DPI phone. If you use it, scale by density yourself or accept different physical sizes per device.
Concrete implementation
The following uses ExtendViewport with a minimum world size of 800x480. It runs in your ApplicationAdapter (or Game/Screen) — no special permissions needed.
private SpriteBatch batch;
private ExtendViewport viewport;
@Override
public void create() {
batch = new SpriteBatch();
// minWorldWidth, minWorldHeight: the smallest area guaranteed visible
viewport = new ExtendViewport(800, 480);
}
@Override
public void resize(int width, int height) {
// true = center the camera on the world
viewport.update(width, height, true);
}
@Override
public void render() {
ScreenUtils.clear(0, 0, 0, 1);
viewport.apply();
batch.setProjectionMatrix(viewport.getCamera().combined);
batch.begin();
// draw in world units here
batch.end();
}Swap ExtendViewport for FitViewport and nothing else changes — that is the point of the abstraction. ExtendViewport also has a four-argument constructor accepting a maximum world size, which caps how much extra world very wide screens can reveal; use it if an unbounded extension would break your game.
Validating the choice
Run the desktop launcher with a resizable window (config.setResizable(true) in the Lwjgl3 launcher) and drag the window through extreme aspect ratios. Then check at least two Android emulator profiles — for example 16:9 and a tall 20:9 phone. What to look for:
- No stretching of sprites (rules out
StretchViewport-style distortion). - With
FitViewport: bars appear symmetrically and no world geometry is clipped. - With
ExtendViewport: the guaranteed minimum area (800x480 here) is always fully visible; extra space shows more world, never bars. - HUD elements anchored via a separate Stage/viewport stay at screen edges.
A quick diagnostic: draw a rectangle exactly at your world bounds. On any screen size it should remain fully visible with ExtendViewport's minimum dimensions, and exactly frame the picture with FitViewport.
Limitations and cautions
Viewport behavior and constructor signatures have shifted across libGdx releases; the examples here assume a current 1.9.x release — confirm against the docs for your exact version. Letterboxing from FitViewport can look unpolished on store screenshots, and ExtendViewport requires your background art to extend beyond the minimum bounds or players will see empty space. Finally, mixing viewport types for world and UI works well but must be tested on a real device, since emulator DPI handling occasionally differs from hardware.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.