What is the difference between Flutter packages widgets.dart, material.dart and cupertino.dart and which one to use?

Viewed 6089

When using flutter, I often come around a type being exposed by different packages in the standard library.

For example the FlutterError but the same applies to other widgets. When writing it and using IntelliSense in VS Code to resolve the package to import so that FlutterError is available, IntelliSense offers me FlutterError in multiple different packages:

In this case, it's available from

  • package:flutter/widgets.dart
  • package:flutter/foundation.dart
  • package:flutter/material.dart
  • package:flutter/cupertino.dart
  • package:flutter/rendering.dart

My understanding is that material.dart and cupertino.dart offer widgets in the particular style - but what is the rest and which package should I import in a MaterialApp(..) that should be platform independent and also run on iOS?

And - if it makes a difference - which one should be used so that platform-specific widgets are automatically used on Android & iOS for native functionality like Date/Timepickers so that a Datepicker is automatically the platform specific variant on Android and the platform specific variant on iOS?

3 Answers

What happens is, the class is defined in a lower part of the framework (here foundation for FlutterError)

And then higher layers of the framework reexport the content of the lower layers, using the export directive.

This is done mainly to make sure that developers don't have to import 5+ different things when they usually need them all.

For example material.dart looks roughltly like this:

export 'package:flutter/widget.dart';

class RaisedButton { }

You can import generic classes from any library. This example:

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

class Foo extends InheritedWidget {
}

Will land to the same InheritedWidget implementation no matter which library you've imported it from. Try to comment out each import and see by Ctrl+Click on the InheritedWidget in AndroidStudio which file with the implementation will be opened.

From my point of view, it's better using one single import import 'package:flutter/material.dart'; rather than two (from material.dart and widgets.dart) if working with material design. If your code is neutral to the UI library then it's obvious to import from system libraries.

You can not use a generic class imported from a neutral system library in intention to switch automatically between Cupertino and Material libraries in compile time. You should use specific UI library widgets explicitly.

If you want to switch between libraries you should develop this logic by yourself. You can read this article https://medium.com/flutter/do-flutter-apps-dream-of-platform-aware-widgets-7d7ed7b4624d as a starting point.

'package:flutter/widgets.dart' is used to create the widgets with dart later which will used inside of your main.dart and make your codes more clearify.

'package:flutter/foundation.dart' have to use if you are going to use the utility classes and functions to create the layers of UIs.

'package:flutter/material.dart' is about to use if you want to use Android framework in your application.And 'package:flutter/cupertino.dart' is about to choose if you want to use IOs UIs in your application.in default, material type is used. It doesn't matter, you are using material type UI or cupertino UI . You can use Android UI for IOs devices and also IOs UIs for Android devices.

Related