Difference between Material & Cupertino in flutter
Tags: flutter, materialdesign, cupertino, dart
Published: 2023-01-30 19:55:31

Ever wonder what's the main difference between [Material app](https://api.flutter.dev/flutter/material/material-library.html) and [Cupertino app](https://api.flutter.dev/flutter/cupertino/cupertino-library.html) in flutter?

Well let's start by defining each type of design.

**Material design** - is a design system built and supported by Google designers and developers. The Material design language was created for any platform, not just Android. When you write a Material app in Flutter, it has the Material look and feel on all devices, even iOS. 

To use the material design library in flutter we always use `import package:flutter/material.dart`, and use the `MaterialApp` class. 

**Cupertino design** - Cupertino is developed by Apple. It is based on Apple's Human Interface Guidelines, which implement the current iOS design language. This library is designed for apps that run on iOS.

To use the material design library in flutter we always use `import package:flutter/cupertino.dart`, and use the `CupertinoApp` class.


**So what the main difference between Material and cupertino app?**

 The Material design language was created for any platform, not just Android. When you write a Material app in Flutter, it has the Material look and feel on all devices, even iOS. If you want your app to look like a standard iOS-styled app, then you would use the Cupertino library.

You can technically run a Cupertino app on either Android or iOS, but (due to licensing issues) Cupertino won't have the correct fonts on Android. For this reason, use an iOS-specific device when writing a Cupertino app.

So what if your in a situation where you want to use cupertino design for IOS apps and material design for other platform, let's see how we can accomplish this.

**Let's  write some code 👨🏽‍💻**

Start by creating a Flutter app, then in the lib folder open `main.dart` file.

Remove the demo app with his respective test folder because we could have some problems if the app name was different (My app).

After the removing the `MyHomePage` class in the main.dart file we should remain with the following code in our main file.

```
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Container(),
    );
  }
}
```

**So let's see the main difference between Material and Cupertino by implementing their code**

The following code uses material design library.

```
import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text("Material App Example"),
        ),
        body: const Center(
          child: Text("Homepage"),
        ),
      ),
      debugShowCheckedModeBanner: false,
    );
  }
}
```
The result is:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vafr91ai2y3mpiy5hfy7.png)

Flutter by default uses Material design during the creation of the app, but we can change it and use Cupertino design.

The following code uses Cupertino design

```
import 'package:flutter/cupertino.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const CupertinoApp(
      home: CupertinoPageScaffold(
        navigationBar: CupertinoNavigationBar(
          middle: Text("Material App Example"),
        ),
        child: Center(
          child: Text("Homepage"),
        ),
      ),
      debugShowCheckedModeBanner: false,
    );
  }
}
```

The result is:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rrjv69tx0jy7ydravo15.png)

You can learn more about Cupertino library [here](https://api.flutter.dev/flutter/cupertino/cupertino-library.html)

**Putting all code together**

First thing first we need to identify the platform that the program is running on, so how do we go for this.

The platform in Flutter is determined by checking the `defaultTargetPlatformand` comparing it with `TargetPlatform` enum.

**Step 1:** Add the import statement
`import ‘package:flutter/foundation.dart’;` to your file.

**Step 2:** Add the following if statement in your code:

```
if (defaultTargetPlatform == TargetPlatform.android){
   // Android specific code
}
else if (defaultTargetPlatform == TargetPlatform.iOS){
   //iOS specific code
}
else {
   //web or desktop specific code
}
```
 

- The above code snippet checks if the current platform is Android or iOS.

- It first detects the current platform using defaultTargetPlatform and compares it with the values inside the TargetPlatform.

- Write a code inside the if statement that you want to perform only in specific platform.

So lets write our full app that detects a platform, first let's create our widgets of each design.

```
// Cupertino Widget
Widget cupertinoWidget(BuildContext context) {
  return const CupertinoApp(
    home: CupertinoPageScaffold(
      navigationBar: CupertinoNavigationBar(
        middle: Text("Material App Example"),
      ),
      child: Center(
        child: Text("Homepage"),
      ),
    ),
    debugShowCheckedModeBanner: false,
  );
}

// Material Widget
Widget materialWidget(BuildContext context) {
  return MaterialApp(
    home: Scaffold(
      appBar: AppBar(
        title: const Text("Material App Example"),
      ),
      body: const Center(
        child: Text("Homepage"),
      ),
    ),
    debugShowCheckedModeBanner: false,
  );
}
```

and finally we will call each widget based on the platform it's running. 

```
if (defaultTargetPlatform == TargetPlatform.android) {
  // Android specific code
  return materialWidget(context);
} else if (defaultTargetPlatform == TargetPlatform.iOS) {
  //iOS specific code
  return cupertinoWidget(context);
} else {
  //web or desktop specific code
  return materialWidget(context);
}
```
And so our full code will be as follow;

```
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    if (defaultTargetPlatform == TargetPlatform.android) {
      // Android specific code
      return materialWidget(context);
    } else if (defaultTargetPlatform == TargetPlatform.iOS) {
      //iOS specific code
      return cupertinoWidget(context);
    } else {
      //web or desktop specific code
      return materialWidget(context);
    }
  }
}

// Cupertino Widget
Widget cupertinoWidget(BuildContext context) {
  return const CupertinoApp(
    home: CupertinoPageScaffold(
      navigationBar: CupertinoNavigationBar(
        middle: Text("Material App Example"),
      ),
      child: Center(
        child: Text("Homepage"),
      ),
    ),
    debugShowCheckedModeBanner: false,
  );
}

// Material Widget
Widget materialWidget(BuildContext context) {
  return MaterialApp(
    home: Scaffold(
      appBar: AppBar(
        title: const Text("Material App Example"),
      ),
      body: const Center(
        child: Text("Homepage"),
      ),
    ),
    debugShowCheckedModeBanner: false,
  );
}
```

And if you try running the app in different platform you will it uses different designs.

**Conclusion**
In this tutorial we learned the main difference between Material design and Cupertino design and how we can implement them in our apps, also we learned how to use specific design based on the platform.