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.