UI Design Dart Notes
UI Design Dart Notes
Dart is an object-oriented language with C-style syntax which can optionally trans
compile into JavaScript. It supports a varied range of programming aids like
interfaces, classes, collections, generics, and optional typing.
Google has released a special build of Chromium – the Dart VM. Using Dartium
means you don’t have to compile your code to JavaScript until you’re ready to test
on other browsers.
Introduction to Dart
This page provides a brief introduction to the Dart language through samples of
its main features.
To learn more about the Dart language, visit the in-depth, individual topic pages
listed under Language in the left side menu.
Every app requires the top-level main() function, where execution starts.
Functions that don't explicitly return a value have the void return type. To
display text on the console, you can use the top-level print() function:
dart
void main() {
print('Hello, World!');
content_copy
Variables
Even in type-safe Dart code, you can declare most variables without explicitly
specifying their type using var. Thanks to type inference, these variables' types
are determined by their initial values:
dart
var image = {
'tags': ['saturn'],
'url': '//path/to/saturn.jpg'
};
content_copy
dart
print('21st century');
print('20th century');
print(month);
year += 1;
content_copy
Read more about control flow statements in Dart,
including break and continue, switch and case, and assert.
Functions
dart
int fibonacci(int n) {
if (n == 0 || n == 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
content_copy
A shorthand => (arrow) syntax is handy for functions that contain a single
statement. This syntax is especially useful when passing anonymous functions as
arguments:
dart
flybyObjects.where((name) =>
name.contains('turn')).forEach(print);
content_copy
Comments
dart
content_copy
Imports
dart
import 'dart:math';
import 'package:test/test.dart';
// Importing files
import 'path/to/my_other_file.dart';
content_copy
Classes
dart
class Spacecraft {
String name;
DateTime? launchDate;
Spacecraft(this.name, this.launchDate) {
// Method.
void describe() {
print('Spacecraft: $name');
if (launchDate != null) {
int years =
DateTime.now().difference(launchDate).inDays ~/ 365;
print('Unlaunched');
content_copy
dart
voyager.describe();
voyager3.describe();
content_copy
dart
content_copy
Here is an example of an enhanced enum declaration of a class describing
planets, with a defined set of constant instances, namely the planets of our own
solar system.
dart
enum Planet {
// ···
uranus(planetType: PlanetType.ice, moons: 27,
hasRings: true),
const Planet(
}
content_copy
dart
if (!yourPlanet.isGiant) {
content_copy
Inheritance
dart
double altitude;
Orbiter(super.name, DateTime super.launchDate,
this.altitude);
content_copy
Mixins
Mixins are a way of reusing code in multiple class hierarchies. The following is a
mixin declaration:
dart
mixin Piloted {
int astronauts = 1;
void describeCrew() {
content_copy
To add a mixin's capabilities to a class, just extend the class with the mixin.
dart
// ···
content_copy
All classes implicitly define an interface. Therefore, you can implement any class.
dart
// ···
content_copy
void describe();
void describeWithEmphasis() {
print('=========');
describe();
print('=========');
content_copy
Avoid callback hell and make your code much more readable by
using async and await.
dart
const oneSecond = Duration(seconds: 1);
// ···
await Future.delayed(oneSecond);
print(message);
content_copy
The method above is equivalent to:
dart
return Future.delayed(oneSecond).then((_) {
print(message);
});
content_copy
As the next example shows, async and await help make asynchronous code
easy to read.
dart
Future<void> createDescriptions(Iterable<String>
objects) async {
try {
if (await file.exists()) {
print(
continue;
await file.create();
}
}
content_copy
You can also use async*, which gives you a nice, readable way to build
streams.
dart
await Future.delayed(oneSecond);
content_copy
Exceptions
dart
if (astronauts == 0) {
content_copy
dart
Future<void> describeFlybyObjects(List<String>
flybyObjects) async {
try {
print(description);
} finally {
flybyObjects.clear();
}
}
content_copy
Note that the code above is asynchronous; try works for both synchronous code
and code in an async function.
Read more about exceptions, including stack traces, rethrow, and the
difference between Error and Exception.
Important concepts
As you continue to learn about the Dart language, keep these facts and concepts
in mind:
merge_typeVersion note
Null safety was introduced in Dart 2.12. Using null safety requires
a language version of at least 2.12.
Although Dart is strongly typed, type annotations are optional because Dart can
infer types. In var number = 101, number is inferred to be of type int.
If you enable null safety, variables can't contain null unless you say they
can. You can make a variable nullable by putting a question mark (?) at the end
of its type. For example, a variable of type int? might be an integer, or it might
be null. If you know that an expression never evaluates to null but Dart
disagrees, you can add ! to assert that it isn't null (and to throw an exception if it
is). An example: int x = nullableButNotNullInt!
When you want to explicitly say that any type is allowed, use the
type Object? (if you've enabled null safety), Object, or—if you must defer
type checking until runtime—the special type dynamic.
Dart tools can report two kinds of problems: warnings and errors.
Warnings are just indications that your code might not work, but they don't
prevent your program from executing. Errors can be either compile-time or run-
time. A compile-time error prevents the code from executing at all; a run-time
error results in an exception being raised while the code executes.
dart:core
The dart:core library (API reference) provides a small but
critical set of built-in functionality. This library is
automatically imported into every Dart program.
dart
print(anObject);
content_copy
For more information on basic strings and toString(),
see Strings in the language tour.
Numbers
The dart:core library defines the num, int, and double
classes, which have some basic utilities for working with
numbers.
dart
assert(int.parse('42') == 42);
assert(int.parse('0x42') == 66);
assert(double.parse('0.50') == 0.5);
content_copy
Or use the parse() method of num, which creates an integer
if possible and otherwise a double:
dart
assert(num.parse('42') is int);
assert(num.parse('0x42') is int);
assert(num.parse('0.50') is double);
content_copy
To specify the base of an integer, add a radix parameter:
dart
content_copy
Use the toString() method to convert an int or double to a
string. To specify the number of digits to the right of the
decimal, use toStringAsFixed(). To specify the number of
significant digits in the string, use toStringAsPrecision():
dart
assert(42.toString() == '42');
assert(123.456.toString() == '123.456');
assert(123.456.toStringAsFixed(2) == '123.46');
assert(123.456.toStringAsPrecision(2) == '1.2e+2');
assert(double.parse('1.2e+2') == 120.0);
content_copy
For more information, see the API documentation
for int, double, and num. Also see the dart:math section
dart
content_copy
Extracting data from a string
dart
// Grab a substring.
assert(parts.length == 3);
assert(parts[0] == 'progressive');
// iterating.
print(char);
assert(codeUnitList[0] == 78);
content_copy
::: In many cases, you want to work with Unicode grapheme
clusters as opposed to pure code units. These are characters
as they are perceived by the user (for example, "🇬🇧" is one
user-perceived character but several UTF-16 code units). For
this, the Dart team provides the characters package. :::
dart
// Convert to uppercase.
// Convert to lowercase.
content_copy
infoNote
These methods don't work for every language. For example, the Turkish
alphabet's dotless I is converted incorrectly.
dart
// Trim a string.
assert(''.isEmpty);
content_copy
Replacing part of a string
dart
assert(greeting != greetingTemplate);
content_copy
Building a string
dart
var sb = StringBuffer();
sb
..write('.');
content_copy
Regular expressions
dart
assert(!allCharacters.contains(numbers));
assert(someDigits.contains(numbers));
content_copy
You can work directly with the RegExp class, too. The Match
class provides access to a regular expression match.
dart
assert(numbers.hasMatch(someDigits));
content_copy
More information
Collections
lightbulbTip
To practice using APIs that are available to both lists and sets, follow the Iterable
collections tutorial.
Lists
assert(grains.isEmpty);
// Add to a list.
fruits.add('kiwis');
fruits.addAll(['grapes', 'bananas']);
assert(fruits.length == 5);
fruits.removeAt(appleIndex);
assert(fruits.length == 4);
assert(fruits.isEmpty);
content_copy
Use indexOf() to find the index of an object in a list:
dart
assert(fruits[0] == 'apples');
assert(fruits.indexOf('apples') == 0);
content_copy
Sort a list using the sort() method. You can provide a sorting
function that compares two objects. This sorting function
must return < 0 for smaller, 0 for the same, and > 0
for bigger. The following example uses compareTo(), which
is defined by Comparable and implemented by String.
dart
// Sort a list.
assert(fruits[0] == 'apples');
content_copy
Lists are parameterized types (generics), so you can specify
the type that a list should contain:
dart
fruits.add('apples');
assert(fruit is String);
content_copy
✗ static analysis: failuredart