Guide to Building Flutter Web & Desktop Applications

Flutter, a cross-platform UI toolkit, is widely known for mobile app development. But with recent updates, Flutter supports web and desktop platforms, allowing developers to create responsive and consistent experiences across platforms with a single codebase. In this blog, we’ll walk through setting up Flutter for web and desktop, explore platform-specific considerations, and create a simple to-do application as a demo.

Building Flutter Web & Desktop Applications

Why Choose Flutter for Web and Desktop?

Flutter’s primary advantage is the capability to run applications across web, mobile, and desktop with a single codebase. For developers, this saves significant time and resources while enabling a consistent user experience.

Setting Up Flutter for Web and Desktop

To get started, you need to enable web and desktop support in Flutter.

Enable Web Support:

flutter config --enable-web

flutter devices # Ensure Chrome or Edge appears as a device

Enable Desktop Support:

flutter config --enable-windows-desktop # For Windows

flutter config --enable-macos-desktop # For macOS

flutter config --enable-linux-desktop # For Linux

Now, create a new Flutter project:

flutter create web_desktop_demo
cd web_desktop_demo

Project Structure Overview

Flutter’s project structure for web and desktop mirrors that of mobile development. The main differences lie in the web, windows, macos, and linux folders, which store platform-specific configurations and assets.

Building the Basic UI

Let’s begin with a basic UI in lib/main.dart to demonstrate a HomeScreen widget.

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Web & Desktop Demo',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: HomeScreen(),
    );
  }
}

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Home Screen')),
      body: Center(child: Text('Welcome to Flutter Web and Desktop!')),
    );
  }
}

Platform Detection with kIsWeb and Platform

You may want to apply platform-specific behavior. Flutter provides the kIsWeb constant and the Platform package to check the platform type.

  1. Using kIsWeb for Web:dartCopy code
import 'package:flutter/foundation.dart';

if (kIsWeb) {
  // Execute web-specific code
}

Using Platform for Desktop:

import 'dart:io';

bool isDesktop = return !kIsWeb && (Platform.isWindows || Platform.isMacOS || Platform.isLinux);

This enables us to run certain code only on specific platforms.

Creating the To-Do Application

Now, let’s create a basic to-do application that works across web and desktop.

Step 1: Define the To-Do Model

class ToDo {
  String id;
  String title;
  bool isComplete;

  ToDo({
    required this.id,
    required this.title,
    this.isComplete = false,
  });
}

Step 2: Set Up State Management with StatefulWidget

In HomeScreen, we’ll create a StatefulWidget to manage the state of the to-do list.

class TodoExample extends StatefulWidget {
  const TodoExample({super.key});

  @override
  State<TodoExample> createState() => _TodoExampleState();
}

class _TodoExampleState extends State<TodoExample> {
  List<Todo> todos = [];
  TextEditingController controller = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Todo Example'),
      ),
      body: Column(
        children: [
          ListView.builder(
              itemCount: todos.length,
              shrinkWrap: true,
              itemBuilder: (context, index) {
                final todo = todos[index];
                return ListTile(
                  title: Text(
                    todo.title,
                    style: TextStyle(
                      decoration:
                          todo.isComplete ? TextDecoration.lineThrough : null,
                    ),
                  ),
                  trailing: Checkbox(
                    value: todo.isComplete,
                    onChanged: (value) {
                      setState(() {
                        todo.isComplete = value!;
                      });
                    },
                  ),
                );
              }),
          Expanded(child: Container()),
          Row(
            children: [
              Expanded(
                  child: TextField(
                controller: controller,
                decoration: const InputDecoration(hintText: 'Enter a todo'),
              )),
              ElevatedButton(
                  onPressed: () {
                    setState(() {
                      todos.add(Todo(
                          id: todos.length.toString(), title: controller.text));
                      controller.clear();
                    });
                  },
                  child: const Text('Add Todo'))
            ],
          )
        ],
      ),
    );
  }
}

Persistent Storage Across Web and Desktop

To save to-do items persistently, we can use:

Example for shared_preferences (Universal for Web and Desktop)

import 'package:shared_preferences/shared_preferences.dart';

Future<void> saveToDoList(List<ToDo> toDoList) async {
final prefs = await SharedPreferences.getInstance();
final taskTitles = toDoList.map((task) => task.title).toList();
prefs.setStringList('toDoList', taskTitles);
}

Future<List<ToDo>> loadToDoList() async {
final prefs = await SharedPreferences.getInstance();
final taskTitles = prefs.getStringList('toDoList') ?? [];
return taskTitles.map((title) => ToDo(
id: DateTime.now().toString(), title: title)).toList();
}

Running the App on Web and Desktop

To test the application on each platform:

For each platform, Flutter adapts the app’s behavior based on platform-specific nuances, giving users a consistent experience.

Conclusion

This demo highlights how easily Flutter handles web and desktop applications with platform-specific adaptations. With a single codebase, you can create a unified application experience across multiple platforms, saving time and resources. Dive in, explore more Flutter libraries, and enhance your apps for web, mobile, and desktop.

Happy Coding!

Explore Other Flutter Topics…

  1. Introduction to Flutter and Dart
  2. Why choose Flutter
  3. Installing Flutter On Your Windows Mac And Linux System
  4. Your first Flutter app
  5. Flutter project structure
  6. Building blocks of Flutter
  7. Stateful vs. Stateless Widgets Explained
  8. Flutter layout system
  9. Flutter text widget
  10. Creating Buttons in Flutter: ElevatedButton, TextButton, and IconButton
  11. Handling User Input with Flutter Forms
  12. Container class in Flutter
  13. Flutter Navigation
  14. Flutter – Pass Data One Screen To Another Screen
  15. Managing Device Orientation in Flutter
  16. Stateful widget lifecycle in Flutter
  17. Future of Flutter
  18. Flutter Themes
  19. Flutter Animations
  20. Flutter AppBar Customization
  21. ListView in Flutter
  22. Flutter GridView
  23. Flutter Expanded Widget
  24. Flutter BottomNavigation Bar
  25. Floating Action Button
  26. Drawer Widgets in Flutter
  27. Form Validation in Flutter
  28. Flutter TextField
  29. Adding AdMob ads to a Flutter app
  30. Building Flutter Web & Desktop Applications
  31. What is Async and Await in Flutter
  32. HTTP requests in Flutter
  33. Parsing JSON in Flutter
  34. Tinder-Style Swipe Cards in Flutter
  35. Flutter Tic Tac Toe Game Tutorial
  36. Flutter Login UI Tutorial
  37. Flutter Card Widget Tutorial
  38. Flutter music player app tutorial
  39. Flutter introduction screens
  40. Shared Preferences in Flutter
  41. SQLite Database in Flutter
  42. Firebase Authentication in Flutter
  43. Firebase Firestore in Flutter
  44. Push Notifications in Flutter
  45. Handling File Uploads in Flutter
  46. Responsive Design in Flutter
  47. Provider in Flutter
  48. Riverpod in Flutter
  49. Flutter BLoC Pattern Tutorial

Leave a Reply

Your email address will not be published. Required fields are marked *