Project structure & resources

Domains: Flutter

Where do I store my image files?

Xamarin.Forms has no platform independent way of storing images, you had to place images in the iOS xcasset folder or on Android, in the various drawable folders.

While Android and iOS treat resources and assets as distinct items, Flutter apps have only assets. All resources that would live in the Resources/drawable-* folders on Android, are placed in an assets folder for Flutter.

Flutter follows a simple density-based format like iOS. Assets might be 1.0x, 2.0x, 3.0x, or any other multiplier. Flutter doesn’t have dps but there are logical pixels, which are basically the same as device-independent pixels. The so-called devicePixelRatio expresses the ratio of physical pixels in a single logical pixel.

The equivalent to Android’s density buckets are:

Android density qualifier Flutter pixel ratio
ldpi 0.75x
mdpi 1.0x
hdpi 1.5x
xhdpi 2.0x
xxhdpi 3.0x
xxxhdpi 4.0x

Assets are located in any arbitrary folder—Flutter has no predefined folder structure. You declare the assets (with location) in the pubspec.yaml file, and Flutter picks them up.

Note that before Flutter 1.0 beta 2, assets defined in Flutter were not accessible from the native side, and vice versa, native assets and resources weren’t available to Flutter, as they lived in separate folders.

As of Flutter beta 2, assets are stored in the native asset folder, and are accessed on the native side using Android’s AssetManager:

As of Flutter beta 2, Flutter still cannot access native resources, nor it can access native assets.

To add a new image asset called my_icon.png to our Flutter project, for example, and deciding that it should live in a folder we arbitrarily called images, you would put the base image (1.0x) in the images folder, and all the other variants in sub-folders called with the appropriate ratio multiplier:

images/my_icon.png       // Base: 1.0x image
images/2.0x/my_icon.png  // 2.0x image
images/3.0x/my_icon.png  // 3.0x image

Next, you’ll need to declare these images in your pubspec.yaml file:

 - images/my_icon.jpeg

You can then access your images using AssetImage:

return new AssetImage("images/a_dot_burr.jpeg");

or directly in an Image widget:

Widget build(BuildContext context) {
  return new Image.asset("images/my_image.png");

More detailed information can be found in Adding assets and images.

Where do I store strings? How do I handle localization?

Unlike .NET which has resx files, Flutter currently doesn’t have a dedicated resources-like system for strings. At the moment, the best practice is to hold your copy text in a class as static fields and accessing them from there. For example:

class Strings {
  static String welcomeMessage = "Welcome To Flutter";

Then in your code, you can access your strings as such:

new Text(Strings.welcomeMessage)

By default, Flutter only supports US English for its strings. If you need to add support for other languages, include the flutter_localizations package. You might also need to add Dart’s intl package to use i10n machinery, such as date/time formatting.

  # ...
    sdk: flutter
  intl: "^0.15.6"

To use the flutter_localizations package, specify the localizationsDelegates and supportedLocales on the app widget:

import 'package:flutter_localizations/flutter_localizations.dart';

new MaterialApp(
 localizationsDelegates: [
   // Add app-specific localization delegate[s] here.
 supportedLocales: [
    const Locale('en', 'US'), // English
    const Locale('he', 'IL'), // Hebrew
    // ... other locales the app supports
  // ...

The delegates contain the actual localized values, while the supportedLocales defines which locales the app supports. The above example uses a MaterialApp, so it has both a GlobalWidgetsLocalizations for the base widgets localized values, and a MaterialWidgetsLocalizations for the Material widgets localizations. If you use WidgetsApp for your app, you don’t need the latter. Note that these two delegates contain “default” values, but you’ll need to provide one or more delegates for your own app’s localizable copy, if you want those to be localized too.

When initialized, the WidgetsApp (or MaterialApp) creates a Localizations widget for you, with the delegates you specify. The current locale for the device is always accessible from the Localizations widget from the current context (in the form of a Locale object), or using the Window.locale.

To access localized resources, use the Localizations.of() method to access a specific localizations class that is provided by a given delegate. Use the intl_translation package to extract translatable copy to arb files for translating, and importing them back into the app for using them with intl.

For further details on internationalization and localization in Flutter, see the internationalization guide, which has sample code with and without the intl package.

Where is my project file?

In Xamarin.Forms you will have a csproj file. The closest equivalent in Flutter is pubspec.yaml, which contains package dependencies and various project details. Similar to .NET Standard, files within the same directory are considered part of the project.

What is the equivalent of Nuget? How do I add dependencies?

In the .NET eco-system, native Xamarin projects and Xamarin.Forms projects had access to Nuget and the inbuilt package management system. Flutter apps contain a native Android app, native iOS app and Flutter app.

In Android, you add dependencies by adding to your Gradle build script. In iOS, you add dependencies by adding to your Podfile.

Flutter uses Dart’s own build system, and the Pub package manager. The tools delegate the building of the native Android and iOS wrapper apps to the respective build systems.

In general, use pubspec.yaml to declare external dependencies to use in Flutter. A good place to find Flutter packages is the Pub site.

Similar pages

Page structure