Displaying a tournament bracket on mobile is surprisingly hard. You need to handle variable-depth trees, connect matches with lines, scale everything to the screen, and make it scrollable. I couldn't find a good Android-native solution, so I built one.
Meet TournamentBracketLib — a lightweight Android library that takes structured match data and renders a full knockout bracket with connectors, animations, and now: team images and match labels.
What does it look like?
Here's a real-world example — the FIFA World Cup 2026 knockout stage, rendered entirely from live API data:
16 matches in the Round of 32, funneling down to a single Final. Each cell shows team flags, scores (or "-" for unplayed matches), and match identifiers.
The Core Idea: 3 Simple Models
The API surface is intentionally minimal. You describe your tournament with three objects:
1. CompetitorData — A team or player
CompetitorData brazil = new CompetitorData("Brazil", "2");
brazil.setImageUrl("https://flagcdn.com/w80/br.png");
Just a name, a score, and an optional image URL. That's it.
2. MatchData — A single match
MatchData match = new MatchData(brazil, argentina);
match.setMatchName("QF - Match 97");
Two competitors face off. Add a label to identify the match in the bracket.
3. ColomnData — A round
ColomnData quarterFinals = new ColomnData(Arrays.asList(qf1, qf2, qf3, qf4));
ColomnData semiFinals = new ColomnData(Arrays.asList(sf1, sf2));
ColomnData finals = new ColomnData(Arrays.asList(finalMatch));
Each column represents one round. The library draws connectors between adjacent columns automatically.
Render it
bracketsView.setBracketsData(Arrays.asList(quarterFinals, semiFinals, finals));
One line. The library handles layout, scrolling, connector lines, and animations.
XML Setup
Drop a BracketsView into your layout with customizable colors:
<com.ventura.bracketslib.BracketsView
android:id="@+id/bracket_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:bracketBackgroundColor="#1c222e"
app:bracketColor="#262e40"
app:bracketTextColor="#fff" />
Dark mode, light mode, team colors — style it however you want.
Real-World Usage: World Cup 2026 App
To demonstrate the library, I built a full app that fetches live World Cup 2026 data and displays:
- Knockout brackets — R32 through the Final, with country flags and match names
- Group standings — All 12 groups with MP/W/D/L/GF/GA/GD/PTS tables
- Pull-to-refresh — Swipe to reload live standings
| Home | Brackets | Group Standings |
|---|---|---|
![]() |
![]() |
![]() |
The bracket data is fetched dynamically from a public API. Games are grouped by type (r32, r16, qf, sf, final), sorted by ID, and rendered — zero hardcoded match IDs.
// Dynamic bracket building — adapts to any tournament structure
Map<String, List<WorldCupGame>> gamesByType = new HashMap<>();
for (WorldCupGame game : games) {
gamesByType.computeIfAbsent(game.getType(), k -> new ArrayList<>()).add(game);
}
String[] rounds = {"r32", "r16", "qf", "sf", "final"};
for (String round : rounds) {
List<WorldCupGame> roundGames = gamesByType.get(round);
Collections.sort(roundGames, (a, b) -> Integer.compare(a.getId(), b.getId()));
// build MatchData list, add ColomnData to bracket
}
If the API adds or removes matches tomorrow, the app adapts automatically.
How to Add It to Your Project
Step 1: Add JitPack to your repositories:
allprojects {
repositories {
google()
mavenCentral()
maven { url 'https://jitpack.io' }
}
}
Step 2: Add the dependency:
dependencies {
implementation 'com.github.emil-ep:TournamentBracketLib:1.1.4'
}
Step 3: Add a BracketsView to your XML, build your data, call setBracketsData(). Done.
Use Cases
This isn't just for football. Anywhere you have elimination-style competition:
- ⚽ Sports apps (football, basketball, tennis, cricket)
- 🎮 Esports tournament trackers
- 🏈 Fantasy league playoff displays
- 💻 Hackathon competition brackets
- 🎯 Any single/double elimination format
Tech Stack (Demo App)
| Library | Purpose |
|---|---|
| TournamentBracketLib | Bracket rendering |
| Retrofit + Gson | API calls |
| Glide | Flag image loading with caching |
| SwipeRefreshLayout | Pull-to-refresh |
| DiffUtil | Efficient RecyclerView updates |
What's Next
- Tap-to-expand match details
- Losers bracket (double elimination) support
- Jetpack Compose version
⭐ If this is useful to you...
I'd really appreciate a star — it helps other developers discover the project:
👉 Star TournamentBracketLib — The library
👉 Star TournamentBrackets — The World Cup 2026 demo app
Links
- 📦 TournamentBracketLib — The library repo
- 📱 TournamentBrackets — Demo app repo
- 🌐 worldcup26.ir — Public API (no auth needed)
What features would you want in a bracket library? Drop a comment — I'm actively developing this and would love your input! 🙌



Top comments (0)