For this workshop we will use Dart Pad - a very useful online utility that can be used to explore Dart programming. Open your favourite browser and navigate to https://dartpad.dev/
Delete the contents of the source code window (that's the left panel), then enter the following code:
void main() {
String h = "Hello";
String w = "World";
print(h + ", " + w);
}
Run the code to check that it works as expected.
Here, we have used the concatenation operator (+
) to concatenate three strings (yes, three).
Try changing the String
literal from "Hello"
to 'Hello'
. Does it still work?
Now change the type of h
and w
from String
to var
. Does it still work? The latter is an example of Dart's type inference.
Now change the code so it uses string interpolation (the $
operator) but outputs the same result as before. You will only need to change the argument to the print(...)
function. Check the code runs correctly.
If you wish to save your previous work, the simplest way is to copy it into a text file using your favourite editor and then save the file somewhere suitable. Clear the contents of the source code window, then enter the following code:
void main() {
int i = 0;
for(i = 0; i < 10; i++){
print(i);
}
}
Run the code. It should count from 0 to 9. Change the code to use a while
loop instead of the for
loop, but produces the same output. Run the code to check it behaves correctly.
Clear the contents of the source code window (after saving the previous code if you wish to), then enter the following code:
class Person {
late String firstName;
late String lastName;
String getFullName() {
return "$firstName $lastName";
}
}
main() {
Person somePerson = new Person();
somePerson.firstName = "Clark";
somePerson.lastName = "Kent";
print(somePerson.getFullName());
}
Here we use late String
instead of String
because the variable is unitialised. By default the Dart compiler objects to unitialised variables (known as ‘null safety').
Add a constructor to your Person
class that initialises the firstName
and lastName
variables. Then change the code in the main
function to use your new constructor.
Run the code to check that it works as expected and show it to the Lab tutor to check it's OK.
Keep the Person
class you created earlier and below it create a new class Employee
that has a field int employeeID
. Your Employee
class should extend the Person class. Here is some skeleton code to get you started:
class Employee extends Person {
//you need to fill in the rest
}
You should include a constructor in your Employee
class that initializes the employeeID
field, but also initializes the two fields of the Person
super class. Here is the signature of the Employee constructor, you need to fill in the rest.
Employee(int employeeID, String firstName, String lastName):super(firstName, lastName){
//one line of code to initialise employeeID;
}
Note the super(...)
keyword is used to call the super class constructor.
Now change the main()
function to create an instance of Employee
rather than Person
and print out their full name and employeeID
. Run the code to check it works correctly.
The reason we've discussed inheritance is that the Flutter framework makes extensive use of inheritance (in Flutter ‘Everything is a Widget'). Here is a simple Hello World Flutter app.
Clear the contents of the source code window (after saving the previous code if you wish to), then enter the following code:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Text('Hello, World!')
)
)
);
}
}
You will notice that to create a Flutter app you need to import the flutter/material.dart package which includes all the classes that make up the Flutter framework.
The class MyApp
is what you would write to start a Flutter project (it doesn't have to be called MyApp!). You will notice the MyApp
class extends the StatelessWidget
class, which is one of the classes provided by the Flutter framework. The StatelessWidget
class contains a method build(...)
that you need to provide an implementation for (override). In this example the implementation returns an instance of the MaterialApp
class, which is another class provided by the Flutter framework.
Run the code to check it works correctly.
The code below
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Text('Hello, World!')
)
)
);
}
calls the MaterialApp
class constructor, which calls the Scaffold
class constructor, which calls the Center
class constructor, which itself calls the Text
class constructor - all these classes are part of the Flutter framework.
This code format style is typical of Flutter and you will come across it a lot. It is similar to the style of coding found in JavaScript. However, it maybe easier to understand what's going on if we rewrite the code in ‘longhand' form:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
Text text = new Text('Hello, World!');
Center center = new Center(child: text);
Scaffold scaffold = new Scaffold(body: center);
MaterialApp matApp = new MaterialApp(home: scaffold);
return matApp;
}
}
The code above is entirely equivalent to the shorthand code shown earlier. I'll let you decide which style you find easier to understand. However, you should get used to the shorthand style as it's the prefered way of doing things in Flutter.
Finally, it should be noted that although the Dart Pad web app is very handy for trying out code quickly, it is not a full IDE and does not provide a proper emulator, so if you want to really explore mobile app development you should use a better IDE and emulator such as provided by Android Studio, which you set up last week.