Theory
The event card, piece by visible piece
FestConnect Flutter's event card needs exactly 4 kinds of visible thing: the poster (an image), the title in confident orange (text), a little star for featured events (an icon), and the Book button.
In Unit 1 each of these was an XML tag plus Java lookups. In Flutter each is a constructor call with named parameters: the Dart functions lesson, now visibly paying rent. Four widgets, each learned the same way: constructor first, then the properties that matter.
Theory
Text and its TextStyle
Text('Garba Night') is the whole minimal form. Styling rides one named parameter:
Text('Garba Night',
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
color: Colors.deepOrange,
),
textAlign: TextAlign.center,
maxLines: 1,
)
Note the shape: the style is ITSELF an object (TextStyle) built with named parameters: widgets configure widgets, objects configure objects, all the way down.
Theory
Image: two constructors, one pubspec toll
Image ships named constructors per source:
Image.asset('assets/garba.png'): an image bundled inside the app. Toll to pay: the file must ALSO be registered in pubspec.yaml underassets:, or the app runs and then fails to find itImage.network('https://fest.example/poster.png'): downloaded at runtime: needs internet, arrives after a delay
Shared properties: width, height, and fit: BoxFit.cover (crop-to-fill, the usual poster choice).
Practical
The card's top: all 4 visible widgets
Column(
children: [
Image.asset('assets/garba.png', // registered in pubspec.yaml!
height: 180, fit: BoxFit.cover),
const Text('Garba Night',
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
color: Colors.deepOrange)),
const Icon(Icons.star, size: 30, color: Colors.amber),
ElevatedButton(
onPressed: () {
// booking logic will live here
},
child: const Text('Book'),
),
const ElevatedButton(
onPressed: null, // null = DISABLED, greyed out
child: Text('Sold out'),
),
],
)
Theory
Buttons and Icon: the small print
ElevatedButton (raised), TextButton (flat), IconButton (just an icon) share the same 2-parameter heart:
onPressed:the tap callback: and the behavioural switch: null means DISABLED: greyed, unclickable, no code needed beyond the nullchild:ANY widget: a Text usually, an Icon, even a Row of both
Icon(Icons.star) draws from the built-in Icons catalogue: rendered from a font, so size: and color: restyle it freely: no image files, no pubspec toll.
Quiz
ElevatedButton(onPressed: null, child: Text('Book')) What does the user see and get?
- A normal button that crashes when tapped
- A greyed-out, disabled button: null for onPressed is Flutter's disable switch
- A compile error: onPressed cannot be null
- An invisible button occupying no space
Show the answer
A greyed-out, disabled button: null for onPressed is Flutter's disable switch
Flutter reads the callback's PRESENCE as the enabled flag: a function means tappable, null means disabled, and the button restyles itself grey automatically: Android's setEnabled(false) folded into one parameter. This is why sold-out events pass null and open events pass their booking closure. Option A imagines null being CALLED: Flutter never invokes what is not there. Option C is wrong because the parameter's type explicitly admits null for exactly this purpose. Option D confuses disabled with absent: the button stays visible, honestly grey.
Think first
The asset that worked on no phone
A classmate adds assets/garba.png to the project folder, writes Image.asset('assets/garba.png'), and the running app shows an error box where the poster should be. The path is correct. What did he skip, and why does Flutter demand it?
Show the answer
The pubspec.yaml registration: under flutter: assets: he must list assets/garba.png (or the assets/ folder). Flutter bundles into the app ONLY what pubspec declares: the build must know every file to package, and a file merely sitting in the folder is invisible to it. (After editing pubspec, re-run: hot reload alone does not re-bundle assets.) Exam pair to keep: Image.asset = bundled + pubspec toll + instant; Image.network = downloaded + internet + delay: choose by where the picture lives.
Watch out
Visible-widget slips
Unregistered assets: the reveal's bug: pubspec.yaml or nothing.
style: 'bold': TextStyle is an OBJECT, not a string: style: TextStyle(fontWeight: FontWeight.bold).
child vs text: buttons have no text: parameter; the label is a child: Text(...): the composition habit.
Expecting network images instantly: they arrive after a download; a loading placeholder is the polished habit (and Unit 5's progress widgets will supply one).
Theory
Constructor + properties: the learning pattern
Notice how each widget was learned: constructor signature, then the 3 or 4 properties that carry its personality: the same properties/events pattern as BCA404's controls and Unit 1's widgets, spelt as named parameters. Every widget in the rest of this subject yields to the same interview. The card's pieces now exist: but they are just stacked. Arranging them beautifully is the invisible widgets' job: Column, Row, Center, Padding, Scaffold and Stack, next.
Summary
Key takeaways
- Text(data, style: TextStyle(fontSize, fontWeight, color), textAlign, maxLines): style is an object.
- Image.asset for bundled files (MUST be registered in pubspec.yaml); Image.network for downloads; fit: BoxFit.cover for posters.
- Buttons: ElevatedButton / TextButton / IconButton with onPressed: + child: (any widget).
- onPressed: null = disabled and auto-greyed: the enable switch is the callback's presence.
- Icon(Icons.name, size, color): font-drawn, freely tinted, no asset toll.
- Learn every widget as constructor + the few properties that matter.
- Memory hook: null sleeps the button, pubspec feeds the image, style is an object.