Last active
March 8, 2023 19:12
-
-
Save ScottS2017/6bddcfd50410c7537770cddbf1b637dc to your computer and use it in GitHub Desktop.
Intro to Flutter Workshop Code for Dartpad.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// You can run this code in Dartpad at https://www.dartpad.dev/6bddcfd50410c7537770cddbf1b637dc | |
import 'package:flutter/material.dart'; | |
/// The only think that belongs in main is runapp. Normally, this | |
/// would be in its own file. | |
void main() { | |
runApp(const MyApp()); | |
} | |
/// This is where we can do a number of things, but here all we're doing | |
/// is setting up a Material design app and telling it to use a color theme | |
/// based on the color blue. | |
class MyApp extends StatelessWidget { | |
const MyApp({super.key}); | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
title: 'Flutter Demo', | |
theme: ThemeData( | |
primarySwatch: Colors.blue, | |
), | |
home: const MyHomePage(title: 'Flutter Demo Home Page'), | |
); | |
} | |
} | |
/// A StatefulWidget never changes its state, it has a State object for | |
/// that. | |
class MyHomePage extends StatefulWidget { | |
const MyHomePage({super.key, required this.title}); | |
final String title; | |
@override | |
State<MyHomePage> createState() => _MyHomePageState(); | |
} | |
class _MyHomePageState extends State<MyHomePage> { | |
late int _counter; | |
/// ///////////////////////////////////////////////////////// | |
/// This does more than just increment a counter. | |
/// setState() will do what it's told in between the | |
/// braces and then, once done, rebuild the state | |
/// object. This in turn rebuilds the elements of | |
/// the UI, so the UI gets updated. | |
/// | |
/// FYI: In dart we don't use public or private. Instead | |
/// we put an underscore in front of the variable or function | |
/// name and this causes it to be marked as private. So | |
/// here, _incrementCounter() is private. | |
void _incrementCounter() { | |
/// When you're first learning to read setState functions it | |
/// can help to imagine there's an unwritten "with" that is part | |
/// of the function name. It's kind of like when you add the words | |
/// "in bed" whenever you read a fortune cookie, but not as much | |
/// fun. | |
/// | |
/// Here, it would read "setStateWith _counter++;" | |
setState(() { | |
_counter++; | |
/// It's easy to understand when you can read words that aren't there! | |
}); | |
} | |
@override void initState() { | |
super.initState(); | |
_counter = 0; | |
} | |
/// This method is run first when createState is run, then it's rerun | |
/// every time setState is called. | |
@override | |
Widget build(BuildContext context) { | |
/// This is cool! I get to be 21 FOREVER! No matter how this gets changed | |
/// below, it will always get reset back to 21 when a new frame is drawn! | |
int myAge = 21; | |
return Scaffold( | |
/// The app bar is that colored bar you see across the top of the screen. | |
appBar: AppBar( | |
/// In a StatefulWidget, the UI code is in the State object, no the | |
/// StatefulWidget. This means that if we want to access any members | |
/// in the StatefulWidget, we need to call them from the parent | |
/// Widget. This ONLY applies to using members of a StatefulWidget | |
/// from within that Widget's State object. | |
title: Text(widget.title), | |
), | |
body: Center( | |
/// Items in Columns are called children, and you can only use Widgets | |
/// as children. | |
child: Column( | |
mainAxisAlignment: MainAxisAlignment.center, | |
/// Here you can see the children parameter actually takes a | |
/// list of Widgets. | |
children: <Widget>[ | |
Text( | |
'You have pushed the button this many times:', | |
style: Theme.of(context).textTheme.headlineMedium, | |
), | |
/// Here is an example of string interpolation (using $) to turn | |
/// a variable's value into a String. You could also do the same | |
/// thing by using _counter.toString() | |
Text( | |
'$_counter', | |
/// Here we use the context. _Always use the context!_ | |
/// The context contains all kinds of information, from the | |
/// TextTheme to the IconTheme, the color scheme and | |
/// you can even add your own custom things to the context | |
/// by using ThemeExtensions and other approaches. | |
/// | |
/// Just for fun, delete ".headlineMedium" | |
style: Theme.of(context).textTheme.headlineMedium, | |
), | |
const SizedBox(height:32.0), | |
Text( | |
'myAge has been incremented $_counter times\nand the current value of myAge is $myAge', | |
textAlign: TextAlign.center, | |
style: Theme.of(context).textTheme.headlineMedium, | |
), | |
], | |
), | |
), | |
/// The FloatingActionButton is placed within the Scaffold | |
/// itself, not within the body. | |
floatingActionButton: FloatingActionButton( | |
/// This is where you tell the button what to do when pressed. | |
/// Here, we tell it to call the _incrementCounter method. | |
/// | |
onPressed: () { | |
_incrementCounter(); | |
myAge += 1; | |
}, | |
/// Another way to do the same thing is to put the setState call in | |
/// the button. It's not the preferred way, but it does allow us to | |
/// show that myAge should be changing and, in reality, it is | |
/// changing. But it's also being recreated every frame, with its | |
/// original value of 21. | |
// onPressed: () { | |
// setState(() { | |
// myAge += 1; | |
// _counter += 1; | |
// }); | |
// }, | |
// | |
tooltip: 'Increment', | |
/// This button can show anything inside of it. We're using an | |
/// icon here because that's what people are used to seeing, but | |
/// we could put text, an image or even a gradient with an | |
/// icon or text in there. | |
child: const Icon(Icons.add), | |
), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment