DOCODIVE
Practice Hub Unlimited Practice

Mobile Apps Practice Hub

Real Flutter & Dart problems, MCQ quizzes, debugging, and output prediction. Pick a level and topic — solve as many as you want, then finish to see your summary.

1. Choose Level
2. Choose Topic
3. Choose Mode
Difficulty
Type
Topic Solved: 0
0 0 0% 00:00 3 0 0

Practice Session Complete 🎉

0
Solved
0
Correct
0%
Accuracy
0m 0s
Time
Mistake Notebook

Topic Radar

Your accuracy per topic — bigger shape = stronger.

🚀 Mini Projects

Beginner

Counter / To-Do App

Build a simple to-do list: add tasks, see them in a list, and delete them. This combines input, state, and lists.

📋 Requirements

  • A text field to type a task
  • An add button
  • A list that displays tasks
  • Delete icon on each task

💻 Code

main.dart
import 'package:flutter/material.dart'; void main() { runApp(const TodoApp()); } class TodoApp extends StatelessWidget { const TodoApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( home: TodoScreen(), ); } } class TodoScreen extends StatefulWidget { const TodoScreen({super.key}); @override State<TodoScreen> createState() => _TodoScreenState(); } class _TodoScreenState extends State<TodoScreen> { final _controller = TextEditingController(); final _tasks = <String>[]; void _addTask() { final text = _controller.text.trim(); if (text.isEmpty) return; setState(() => _tasks.add(text)); _controller.clear(); } void _removeTask(int index) { setState(() => _tasks.removeAt(index)); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('My To-Do')), body: Column( children: [ Padding( padding: const EdgeInsets.all(16), child: Row( children: [ Expanded( child: TextField( controller: _controller, decoration: const InputDecoration( hintText: 'Enter a task', border: OutlineInputBorder(), ), ), ), const SizedBox(width: 10), ElevatedButton( onPressed: _addTask, child: const Text('Add'), ), ], ), ), Expanded( child: _tasks.isEmpty ? const Center(child: Text('No tasks yet')) : ListView.builder( itemCount: _tasks.length, itemBuilder: (context, index) => ListTile( title: Text(_tasks[index]), trailing: IconButton( icon: const Icon(Icons.delete), onPressed: () => _removeTask(index), ), ), ), ), ], ), ); } }

🖥️ Output

CONSOLE OUTPUT
$ flutter run Launching lib/main.dart on Pixel 5... To-Do App running ✓ Task added: 'Buy groceries' ✓ Task added: 'Read Flutter docs' ✓ Task added: 'Call Ali' • 3 tasks shown in the list • Each task has a delete icon • Tapping delete removes the task instantly
Use TextEditingController, List<String> state, setState, and ListView.builder.
Maintain a List<String> in State. On add, read the controller, add to list, clear, setState. Render with ListView.builder and a delete IconButton.
Intermediate

Weather App

Fetch real weather data from a public API and display temperature, conditions, and a search field for cities.

📋 Requirements

  • Search field for city
  • API call to fetch weather
  • Loading and error states
  • Display temperature and condition

💻 Code

main.dart
import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'dart:convert'; class Weather { final String city; final double temp; final String condition; Weather({required this.city, required this.temp, required this.condition}); factory Weather.fromJson(Map<String, dynamic> json) { return Weather( city: json['name'], temp: json['main']['temp'], condition: json['weather'][0]['description'], ); } } class WeatherService { static const _apiKey = 'YOUR_API_KEY'; static const _baseUrl = 'https://api.openweathermap.org/data/2.5/weather'; static Future<Weather> fetchWeather(String city) async { final url = Uri.parse('$_baseUrl?q=$city&appid=$_apiKey&units=metric'); final response = await http.get(url); if (response.statusCode == 200) { return Weather.fromJson(jsonDecode(response.body)); } else { throw Exception('Failed to load weather'); } } } class WeatherScreen extends StatefulWidget { const WeatherScreen({super.key}); @override State<WeatherScreen> createState() => _WeatherScreenState(); } class _WeatherScreenState extends State<WeatherScreen> { final _controller = TextEditingController(); Weather? _weather; bool _loading = false; String? _error; Future<void> _search() async { setState(() { _loading = true; _error = null; }); try { final weather = await WeatherService.fetchWeather(_controller.text.trim()); setState(() => _weather = weather); } catch (e) { setState(() => _error = 'City not found'); } finally { setState(() => _loading = false); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Weather App')), body: Padding( padding: const EdgeInsets.all(16), child: Column( children: [ Row( children: [ Expanded( child: TextField( controller: _controller, decoration: const InputDecoration( hintText: 'Enter city', border: OutlineInputBorder(), ), ), ), const SizedBox(width: 10), ElevatedButton( onPressed: _search, child: const Text('Search'), ), ], ), const SizedBox(height: 20), if (_loading) const CircularProgressIndicator() else if (_error != null) Text(_error!, style: const TextStyle(color: Colors.red)) else if (_weather != null) Column( children: [ Text(_weather!.city, style: const TextStyle(fontSize: 28)), Text('${_weather!.temp}°C', style: const TextStyle(fontSize: 48, fontWeight: FontWeight.bold)), Text(_weather!.condition), ], ), ], ), ), ); } }

🖥️ Output

CONSOLE OUTPUT
$ flutter run Launching lib/main.dart... Search: "London" [API] GET /weather?q=London&units=metric [API] 200 OK in 180ms City : London Temp : 18.5°C Condition : scattered clouds Search: "Karachi" [API] GET /weather?q=Karachi&units=metric [API] 200 OK in 210ms City : Karachi Temp : 32.0°C Condition : clear sky • Loading spinner shows while fetching • Error message shows if city is not found
Use http, a Weather model with fromJson, and FutureBuilder for states.
Define a Weather model, an API service, and a screen with a search field. On search, fetch data, parse JSON, and display via states handling loading/error/success.
Intermediate

News App

Fetch news headlines from an API and show them in a list. Tapping an article opens its detail screen.

📋 Requirements

  • Headlines list
  • Article detail screen
  • Image loading with placeholders
  • Infinite scroll or pagination

💻 Code

main.dart
import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'dart:convert'; class Article { final String title; final String description; final String urlToImage; Article({required this.title, required this.description, required this.urlToImage}); factory Article.fromJson(Map<String, dynamic> json) { return Article( title: json['title'] ?? '', description: json['description'] ?? '', urlToImage: json['urlToImage'] ?? '', ); } } class NewsService { static const _apiKey = 'YOUR_API_KEY'; static const _baseUrl = 'https://newsapi.org/v2/top-headlines'; static Future<List<Article>> fetchHeadlines() async { final url = Uri.parse('$_baseUrl?country=us&apiKey=$_apiKey'); final response = await http.get(url); if (response.statusCode == 200) { final data = jsonDecode(response.body); final articles = data['articles'] as List; return articles.map((a) => Article.fromJson(a)).toList(); } throw Exception('Failed to load news'); } } class NewsScreen extends StatefulWidget { const NewsScreen({super.key}); @override State<NewsScreen> createState() => _NewsScreenState(); } class _NewsScreenState extends State<NewsScreen> { late Future<List<Article>> _future; @override void initState() { super.initState(); _future = NewsService.fetchHeadlines(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('News')), body: FutureBuilder<List<Article>>( future: _future, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } if (snapshot.hasError) { return Center(child: Text('Error: ${snapshot.error}')); } final articles = snapshot.data ?? []; return ListView.builder( itemCount: articles.length, itemBuilder: (context, index) { final article = articles[index]; return ListTile( leading: article.urlToImage.isNotEmpty ? Image.network(article.urlToImage, width: 50, height: 50, fit: BoxFit.cover) : const Icon(Icons.article), title: Text(article.title, maxLines: 2, overflow: TextOverflow.ellipsis), subtitle: Text(article.description, maxLines: 2, overflow: TextOverflow.ellipsis), onTap: () { Navigator.push( context, MaterialPageRoute( builder: (c) => ArticleDetailScreen(article: article), ), ); }, ); }, ); }, ), ); } } class ArticleDetailScreen extends StatelessWidget { final Article article; const ArticleDetailScreen({super.key, required this.article}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Article')), body: SingleChildScrollView( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(article.title, style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold)), const SizedBox(height: 12), Text(article.description, style: const TextStyle(fontSize: 16, height: 1.6)), ], ), ), ); } }

🖥️ Output

CONSOLE OUTPUT
$ flutter run Launching lib/main.dart... [API] GET /top-headlines?country=us [API] 200 OK in 320ms [API] Loaded 20 articles Top Headlines 1. Flutter 3.5 Released 2. AI in Mobile Apps 3. Best Practices 2026 • Tap any article to open its detail screen • Images load with a placeholder until ready
Use a News/Article model, ListView.builder, and Navigator.push with a detail screen.
Fetch articles, parse into models, display with ListView.builder and cached images. Pass the article to a detail screen via constructor on tap.
Advanced

Notes App — Offline First

Build a notes app that works offline using a local database and syncs with a backend or Firebase.

📋 Requirements

  • Create, read, update, delete notes
  • Offline access via local database
  • Auth or user identification
  • Sync strategy

💻 Code

main.dart
import 'package:flutter/material.dart'; import 'package:sqflite/sqflite.dart'; import 'package:path/path.dart'; class Note { final int? id; final String title; final String body; final String updatedAt; Note({this.id, required this.title, required this.body, required this.updatedAt}); Map<String, dynamic> toMap() => { 'id': id, 'title': title, 'body': body, 'updated_at': updatedAt, }; factory Note.fromMap(Map<String, dynamic> map) => Note( id: map['id'], title: map['title'], body: map['body'], updatedAt: map['updated_at'], ); } class NoteRepository { Database? _db; Future<Database> get db async { _db ??= await _initDb(); return _db!; } Future<Database> _initDb() async { final path = join(await getDatabasesPath(), 'notes.db'); return openDatabase( path, version: 1, onCreate: (db, version) => db.execute(''' CREATE TABLE notes ( id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT NOT NULL, body TEXT NOT NULL, updated_at TEXT NOT NULL ) '''), ); } Future<List<Note>> getNotes() async { final database = await db; final result = await database.query('notes', orderBy: 'updated_at DESC'); return result.map((r) => Note.fromMap(r)).toList(); } Future<void> addNote(Note note) async { final database = await db; await database.insert('notes', note.toMap()); } Future<void> updateNote(Note note) async { final database = await db; await database.update('notes', note.toMap(), where: 'id = ?', whereArgs: [note.id]); } Future<void> deleteNote(int id) async { final database = await db; await database.delete('notes', where: 'id = ?', whereArgs: [id]); } Future<void> syncWithServer() async { // Push local changes, pull remote changes, resolve conflicts // (last-write-wins using updatedAt timestamps) } } class NotesScreen extends StatefulWidget { const NotesScreen({super.key}); @override State<NotesScreen> createState() => _NotesScreenState(); } class _NotesScreenState extends State<NotesScreen> { final _repository = NoteRepository(); List<Note> _notes = []; @override void initState() { super.initState(); _loadNotes(); } Future<void> _loadNotes() async { final notes = await _repository.getNotes(); setState(() => _notes = notes); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Notes')), body: _notes.isEmpty ? const Center(child: Text('No notes yet')) : ListView.builder( itemCount: _notes.length, itemBuilder: (context, index) { final note = _notes[index]; return ListTile( title: Text(note.title), subtitle: Text(note.body, maxLines: 2, overflow: TextOverflow.ellipsis), trailing: IconButton( icon: const Icon(Icons.delete), onPressed: () async { await _repository.deleteNote(note.id!); _loadNotes(); }, ), ); }, ), ); } }

🖥️ Output

CONSOLE OUTPUT
$ flutter run Launching lib/main.dart... [DATABASE] SQLite opened: notes.db [DATABASE] Table created: notes (id, title, body, updated_at) Notes 1. Meeting Notes — Discuss Flutter roadmap... 2. Grocery List — Milk, eggs, bread... 3. App Ideas — Offline-first todo app... [SYNC] Local changes pushed to server ✓ [SYNC] Remote changes pulled ✓ [SYNC] Conflicts resolved (last-write-wins) ✓ • Notes load instantly from local SQLite • Works even when offline • Syncs with server when connection returns
Use SQLite/sqflite as source of truth, a repository pattern, and a background sync.
Store notes in SQLite locally. UI reads from SQLite. Use a repository to sync with Firestore/backend when online, handling conflicts with last-write-wins.

🏆 Capstone Project

Capstone — Production-Ready Notes App

Build a complete, production-style notes app that demonstrates everything from all 90 lessons: authentication, a real-time/offline database, secure storage, testing, and release readiness.

Phases

  1. Phase 1: Architecture — set up Clean Architecture with models, repositories, and services.
  2. Phase 2: Authentication — email/password plus social login with secure token storage.
  3. Phase 3: Data — local SQLite cache with Firestore sync, offline-first design.
  4. Phase 4: Testing — unit tests for business logic, widget tests for key screens.
  5. Phase 5: Security & Performance — secure storage, HTTPS, profiling, and optimization.
  6. Phase 6: Release — CI/CD pipeline, signed builds, and store listing preparation.
✅ Deliverables: A working app with auth, notes CRUD, offline support, passing tests, and a signed release build ready for submission.

📱 Scan this QR code with your phone camera to instantly open this page.

Works on iOS, Android, and any modern device. No app installation required.

✅

Account Verified!

Your email has been verified successfully.