Bahir Dar University-BiT-Faculty of Computing
Course Name:-Mobile Application
Development
Chapter 3: Flutter Basics
compiled by Samuel. Ashagrre
MOBILE APPLICATION DEVELOPMENT 1
Understanding Widgets
MOBILE APPLICATION DEVELOPMENT 2
Understanding Widgets
A widget is a key component of the user interface (UI) in Flutter.
Widgets are used to describe the structure and layout of your
application’s UI elements, such as buttons, text fields, images,
containers, and more. The UI is rebuilt when the widget tree changes
because Flutter is built on a reactive architecture.
MOBILE APPLICATION DEVELOPMENT 3
Understanding Widgets
Widgets Are Immutable: Widgets in Flutter are immutable, which
means once you create a widget, you cannot modify its properties
directly. Instead, when you want to make changes to the UI, you
typically create a new widget with the desired changes.
Widget Tree: Flutter apps are constructed using a hierarchy of widgets,
known as the widget tree. At the root of the tree is the MaterialApp or
CupertinoApp, which defines the overall structure of the app. Within
this tree, widgets nest inside one another to create complex UIs.
MOBILE APPLICATION DEVELOPMENT 4
Understanding Widgets
The below image is a simple visual representation of the widget tree.
MOBILE APPLICATION DEVELOPMENT 5
Understanding Widgets
We can create the Flutter widget like this:
Class ImageWidget extends StatelessWidget {
// Class Stuff
}
MOBILE APPLICATION DEVELOPMENT 6
Understanding Widgets
Hello World Example
import 'package:flutter/material.dart'; @override
Widget build(BuildContext context) {
return Scaffold(
class MyHomePage extends StatelessWidget { appBar: AppBar(
title: Text(this.title),
MyHomePage({Key key, this.title}) : super(key: key);
),
// This widget is the home page of your application. body: Center(
child: Text('Hello World'),
final String title; ),
);
}
}
MOBILE APPLICATION DEVELOPMENT 7
Types of Widget
We can split the Flutter widget into two categories:
Visible (Output and Input)
Invisible (Layout and Control)
MOBILE APPLICATION DEVELOPMENT 8
Text
A Text widget holds some text to display on the screen. We can align the text
widget by using textAlign property, and style property allow the
customization of Text that includes font, font weight, font style, letter spacing,
color, and many more.
MOBILE APPLICATION DEVELOPMENT 9
Text
The most common properties of the Text widget are as follows:
style: A class that composes the styling of a text. It exposes properties that allow
changing the text color, background, font line height, font size, and so on.
textAlign: Controls the text horizontal alignment, giving options such as center
aligned or justified, for example.
maxLines: Allows specifying a maximum number of lines for the text that will be
truncated if the limit is exceeded.
overflow: Will define how the text will be truncated on overflows, giving options
such as specifying a max-lines limit.
MOBILE APPLICATION DEVELOPMENT 10
Text
Widget build(BuildContext context) {
Simple Text Widget return MaterialApp(
home: Scaffold(
import 'package:flutter/material.dart'; appBar: AppBar(
void main() => runApp(MyApp()); title: Text(
'Hello Flutter',
class MyApp extends StatelessWidget { style: TextStyle(color: Colors.blue, fontSize: 20),
)),
@override ),
);
}
}
MOBILE APPLICATION DEVELOPMENT 11
Text
class DefaultTextStyleExample extends StatelessWidget { body: DefaultTextStyle.merge(
const DefaultTextStyleExample({super.key}); style: const TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
@override
),
Widget build(BuildContext context) { child: const Center(
return Scaffold( child: Text('BDU'),
appBar: AppBar(title: const Text('DefaultTextStyle.merge Sample')), ),
// Inherit MaterialApp text theme and override font size and font weight.
),
);
}
}
MOBILE APPLICATION DEVELOPMENT 12
Text:Using RichText for Complex Styling
void main() => runApp(MyApp()); style: TextStyle(fontSize: 24, color: Colors.black),
class MyApp extends StatelessWidget { children: <TextSpan>[
TextSpan(
@override
text: 'bold',
Widget build(BuildContext context) { style: TextStyle(fontWeight: FontWeight.bold)),
return MaterialApp( TextSpan(text: ' world!'),
],
home: Scaffold( ),
body: Center( ),
),
child: RichText( ),
text: TextSpan( );
}
text: 'Hello ',
}
MOBILE APPLICATION DEVELOPMENT 13
Image
class MyApp extends StatelessWidget { body: Center(
@override child: Image(
Widget build(BuildContext context) { image: AssetImage('assets/cat.png'), // Replace
return MaterialApp(
'image_example.png' with your image asset path
width: 200, // Set width of the image
home: Scaffold(
height: 200, // Set height of the image
appBar: AppBar( fit: BoxFit.contain, // Set how the image should be
title: Text('Image Widget Example'), inscribed into the space
), ),
),
),
);
}
}
MOBILE APPLICATION DEVELOPMENT 14
Icon
class MyApp extends StatelessWidget { body: Center(
@override child: Icon(
Widget build(BuildContext context) { Icons.favorite, // Specifies the icon to be displayed
size: 50, // Sets the size of the icon
return MaterialApp(
color: Colors.red, // Sets the color of the icon
home: Scaffold( ),
appBar: AppBar( ),
title: Text('Icon Widget Example'), ),
);
),
}
}
MOBILE APPLICATION DEVELOPMENT 15
The Scaffold widget
the Scaffold widget in Flutter serves as a structural component for
implementing basic material design visual layouts. It provides an easy way to
implement the most common elements of a typical mobile application, such
as an app bar, floating action button, drawer, and bottom navigation bar.
MOBILE APPLICATION DEVELOPMENT 16
The Scaffold widget
class MyHomePage extends StatelessWidget { body: Center(
child: Text('Hello, Scaffold!'),
@override ),
Widget build(BuildContext context) { floatingActionButton: FloatingActionButton(
onPressed: () {
return Scaffold( // Add your onPressed functionality here
appBar: AppBar( print('Floating Action Button pressed');
},
title: Text('Scaffold Example'), child: Icon(Icons.add),
), ),
);
}
}
}
MOBILE APPLICATION DEVELOPMENT 17
The Scaffold widget
class MyHomePage extends StatelessWidget { body: Center(
child: Text('Hello, Scaffold!'),
@override ),
Widget build(BuildContext context) { floatingActionButton: FloatingActionButton(
onPressed: () {
return Scaffold( // Add your onPressed functionality here
appBar: AppBar( print('Floating Action Button pressed');
},
title: Text('Scaffold Example'), child: Icon(Icons.add),
), ),
);
}
}
}
MOBILE APPLICATION DEVELOPMENT 18
The AppBar widget
The AppBar widget in Flutter represents the app bar, a
material design component typically used as the topmost
element of an application's UI.
It often contains the title of the current screen, leading
and trailing widgets, and may have additional features like
actions, tabs, or navigation controls.
MOBILE APPLICATION DEVELOPMENT 19
The AppBar widget
class MyApp extends StatelessWidget { IconButton(
@override icon: Icon(Icons.more_vert),
Widget build(BuildContext context) { onPressed: () {
return MaterialApp( // Add your more options functionality here
home: Scaffold( print('More options button pressed');
appBar: AppBar( },
title: Text('AppBar Example'), ),
actions: [ ],
IconButton( ),
icon: Icon(Icons.search),
body: Center(
onPressed: () {
child: Text('Hello, AppBar!'),
// Add your search functionality here
),
print('Search button pressed');
),
},
);
}
),
}
MOBILE APPLICATION DEVELOPMENT 20
Stateless vs. Stateful Widgets
Stateless Widgets
• Stateless widgets are immutable, meaning their properties cannot change once they
are created.
• They do not have any internal state that can change during the lifetime of the widget.
• Stateless widgets are simple and lightweight, as they do not require managing state.
• They are primarily used for representing UI components that do not change over time
or depend on external factors.
• Examples of stateless widgets include Text, Icon, Image, FlatButton, etc
MOBILE APPLICATION DEVELOPMENT 21
Stateless vs. Stateful Widgets
Stateful Widgets
• Stateful widgets, on the other hand, have mutable state, allowing their properties to
change over time.
• They maintain state internally and can be updated based on user interactions, data
changes, or other factors.
• Stateful widgets typically consist of two classes: a StatefulWidget class and a
corresponding State class that manages the widget's state.
• They are used for representing UI components that need to maintain state or
respond to user input.
• Examples of stateful widgets include TextField, Checkbox, Slider, ListView, etc.
MOBILE APPLICATION DEVELOPMENT 22
Interactivity Widgets
MOBILE APPLICATION DEVELOPMENT 23
Drawer Widgets
Drawer widget is an interactive widget that allows users to access navigation
or additional options by swiping from the edge of the screen or tapping on a
menu icon.
It's commonly used to provide navigation options in mobile applications,
similar to a side menu or navigation drawer.
MOBILE APPLICATION DEVELOPMENT 24
ListTile(
title: Text('Item 1'),
onTap: () {
Drawer Widgets // Action when Item 1 is tapped
Navigator.pop(context);
class MyHomePage extends StatelessWidget { },
@override ),
Widget build(BuildContext context) { ListTile(
return Scaffold( title: Text('Item 2'),
appBar: AppBar( onTap: () {
title: Text('Drawer Example'), // Action when Item 2 is tapped
), Navigator.pop(context);
drawer: Drawer( },
child: ListView( ),
padding: EdgeInsets.zero, ],
children: <Widget>[ ),
DrawerHeader( ),
child: Text('Drawer Header'), body: Center(
decoration: BoxDecoration( child: Text('Hello, Drawer!'),
color: Colors.blue, ),
), );
), }
} APPLICATION DEVELOPMENT
MOBILE 25
Input and Forms: TextField widget
class MyApp extends StatelessWidget { body: Center(
child: Padding(
@override padding: EdgeInsets.all(20.0),
Widget build(BuildContext context) { child: TextField(
decoration: InputDecoration(
return MaterialApp( labelText: 'Enter your name',
home: Scaffold( border: OutlineInputBorder(),
),
appBar: AppBar( ),
title: Text('TextField Example'), ),
),
), ),
);
}
}
MOBILE APPLICATION DEVELOPMENT 26
Input and Forms: TextField widget
class MyApp extends StatelessWidget { body: Center(
child: Padding(
@override padding: EdgeInsets.all(20.0),
Widget build(BuildContext context) { child: TextField(
decoration: InputDecoration(
return MaterialApp( labelText: 'Enter your name',
home: Scaffold( border: OutlineInputBorder(),
),
appBar: AppBar( ),
title: Text('TextField Example'), ),
),
), ),
);
}
}
MOBILE APPLICATION DEVELOPMENT 27
Input and Forms: Checkbox widget
class _MyHomePageState extends body: Center(
State<MyHomePage> { child: Checkbox(
value: _isChecked,
bool _isChecked = false; onChanged: (value) {
setState(() {
_isChecked = value!;
@override });
Widget build(BuildContext context) { },
),
return Scaffold( ),
appBar: AppBar( );
}
title: Text('Checkbox Example'), }
),
MOBILE APPLICATION DEVELOPMENT 28
Input and Forms: Radio widget
@override mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Widget build(BuildContext context) { RadioListTile<String>(
return Scaffold( title: Text('Option 1'),
value: 'Option 1',
appBar: AppBar( groupValue: _selectedOption,
onChanged: (String? value) {
title: Text('Radio Example'),
setState(() {
), _selectedOption = value;
});
body: Center(
},
child: Column( ),
MOBILE APPLICATION DEVELOPMENT 29
Input and Forms: Radio widget
RadioListTile<String>( RadioListTile<String>(
title: Text('Option 3'),
title: Text('Option 2'),
value: 'Option 3',
value: 'Option 2', groupValue: _selectedOption,
groupValue: _selectedOption, onChanged: (String? value) {
onChanged: (String? value) { setState(() {
_selectedOption = value;
setState(() { });
_selectedOption = value; },
}); ),
],
},
),
), ),
);
}
}
MOBILE APPLICATION DEVELOPMENT 30
Input and Forms: Radio widget
RadioListTile<String>( RadioListTile<String>(
title: Text('Option 3'),
title: Text('Option 2'),
value: 'Option 3',
value: 'Option 2', groupValue: _selectedOption,
groupValue: _selectedOption, onChanged: (String? value) {
onChanged: (String? value) { setState(() {
_selectedOption = value;
setState(() { });
_selectedOption = value; },
}); ),
],
},
),
), ),
);
}
}
MOBILE APPLICATION DEVELOPMENT 31
Input and Forms: Button
ElevatedButton
OutlinedButton
TextButton
IconButton
FloatingActionButton
MOBILE APPLICATION DEVELOPMENT 32
Button: ElevatedButton
body: Center(
child: ElevatedButton(
class MyApp extends StatelessWidget { onPressed: () {
@override // Add your onPressed functionality here
Widget build(BuildContext context) { print('Button pressed');
return MaterialApp( },
home: Scaffold( child: Text('ElevatedButton'),
appBar: AppBar( ),
title: Text('ElevatedButton Example'), ),
), ),
);
}
}
MOBILE APPLICATION DEVELOPMENT 33
Button: OutlinedButton
body: Center(
child: OutlinedButton(
@override child: Text("Tap on this"),
Widget build(BuildContext context) { style: OutlinedButton.styleFrom(
return Scaffold( primary: Colors.red,
appBar: AppBar( side: BorderSide(
title: Text("AppMaking.co"), color: Colors.red,
centerTitle: true, ),
backgroundColor: Colors.blue[900], ),
), onPressed: () {},
),
),
);
MOBILE APPLICATION DEVELOPMENT 34
}
Button: TextButton
body: Center(
child: TextButton(
class MyApp extends StatelessWidget { onPressed: () {
@override // Add your onPressed functionality here
Widget build(BuildContext context) { print('Button pressed');
return MaterialApp( },
home: Scaffold( child: Text('TextButton'),
appBar: AppBar( ),
title: Text('TextButton Example'), ),
), ),
);
}
}
MOBILE APPLICATION DEVELOPMENT 35
Reading Assignment
IconButton
Floating Action
MOBILE APPLICATION DEVELOPMENT 36
Invisible (Layout and Control) widgets
In Flutter, invisible widgets, also known as layout and control widgets,
are widgets that are used to manage the layout and behavior of other
widgets but are not directly visible on the screen. These widgets help in
organizing and controlling the appearance and behavior of visible
widgets.
MOBILE APPLICATION DEVELOPMENT 37
Invisible (Layout and Control) widgets
Container: The Container widget is a versatile widget that can contain other widgets and
provides properties for layout, padding, margin, decoration, and more. It's commonly used
to create spacing between widgets, apply background colors, or add borders.
Row and Column: These widgets are used to arrange child widgets in a horizontal (Row) or
vertical (Column) direction. They can contain multiple children and provide properties for
controlling alignment, spacing, and flexibility.
Stack: The Stack widget is used to overlay multiple widgets on top of each other. Widgets
in a Stack are positioned relative to each other or relative to the Stack itself. This is useful for
creating complex layouts where widgets need to overlap.
ListView: The ListView widget is used to create a scrollable list of children. It's commonly
used when you have a large number of children that need to be scrolled vertically or
horizontally.
MOBILE APPLICATION DEVELOPMENT 38
Invisible (Layout and Control) widgets
GridView: Similar to ListView, the GridView widget is used to create a scrollable grid of children. It's
useful for displaying items in a grid layout, where each item can have a fixed or flexible size.
Spacer: The Spacer widget is used to create flexible space within a Row or Column. It expands to fill
the available space along the main axis and can be used to distribute space evenly between widgets.
Expanded: The Expanded widget is used to make a child widget expand to fill the available space
along the main axis of its parent Row, Column, or Flex widget. It's commonly used in combination
with Row or Column to create flexible layouts.
Flexible: Similar to Expanded, the Flexible widget is used to make a child widget flexible within its
parent's constraints. However, unlike Expanded, it allows the child to grow or shrink based on its flex
factor.
MOBILE APPLICATION DEVELOPMENT 39
Container
the Container widget is a versatile widget used to contain other
widgets and provide properties for layout, padding, margin, decoration,
and more.
MOBILE APPLICATION DEVELOPMENT 40
Container
body: Center(
child: Container(
class MyApp extends StatelessWidget { width: 200,
height: 200,
@override color: Colors.blue,
Widget build(BuildContext context) { child: Center(
child: Text(
return MaterialApp( 'Hello, Flutter!',
home: Scaffold( style: TextStyle(color: Colors.white, fontSize: 20),
),
appBar: AppBar( ),
title: Text('Container Widget Example'), ),
),
), ),
);
}
}
MOBILE APPLICATION DEVELOPMENT 41
Row and Column widget
the Row and Column widgets are used to arrange child
widgets horizontally (Row) or vertically (Column). They are
essential for building layouts in Flutter applications.
MOBILE APPLICATION DEVELOPMENT 42
Row Widget:
The Row widget arranges its children in a horizontal line. It lays
out its children along the main axis (horizontal by default) and
allows them to occupy the cross-axis (vertical by default)
according to their sizes.
MOBILE APPLICATION DEVELOPMENT 43
Row Widget:
Basic Usage:
Row(
children: <Widget>[
Text('Hello'),
Text('World'),
],
)
MOBILE APPLICATION DEVELOPMENT 44
Column Widget:
The Column widget arranges its children in a vertical column. It lays
out its children along the main axis (vertical by default) and allows
them to occupy the cross-axis (horizontal by default) according to
their sizes.
MOBILE APPLICATION DEVELOPMENT 45
Column Widget:
Basic Usage:
Column(
children: <Widget>[
Text('Hello'),
Text('World'),
],
)
MOBILE APPLICATION DEVELOPMENT 46
Example:
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start, Container(
children: <Widget>[ width: 100,
Text('Hello'), height: 100,
Row(
color: Colors.blue,
),
mainAxisAlignment: MainAxisAlignment.spaceBetween,
],
children: <Widget>[ )
Text('Flutter'),
Text('Widgets'),
],
),
MOBILE APPLICATION DEVELOPMENT 47
ListView
the ListView widget is used to create a scrollable list of children. It's a
commonly used widget when you have a large number of children that need to
be scrolled vertically or horizontally. The ListView widget efficiently manages
the memory by only loading and displaying the children that are currently
visible on the screen.
MOBILE APPLICATION DEVELOPMENT 48
Basic Vertical ListView:
ListView(
children: <Widget>[
ListTile(title: Text('Item 1')),
ListTile(title: Text('Item 2')),
ListTile(title: Text('Item 3')),
// Add more list items as needed
],
)
MOBILE APPLICATION DEVELOPMENT 49
Basic Horizontal ListView:
ListView(
scrollDirection: Axis.horizontal,
children: <Widget>[
ListTile(title: Text('Item 1')),
ListTile(title: Text('Item 2')),
ListTile(title: Text('Item 3')),
// Add more list items as needed
],
)
MOBILE APPLICATION DEVELOPMENT 50
GridView
the GridView widget is used to create a scrollable grid of children. It's similar to
the ListView widget but arranges its children in a two-dimensional grid layout,
with rows and columns. The GridView widget efficiently manages the memory by
only loading and displaying the children that are currently visible on the screen.
MOBILE APPLICATION DEVELOPMENT 51
Basic GridView:
GridView.count(
crossAxisCount: 2, // Number of columns
children: <Widget>[
ListTile(title: Text('Item 1')),
ListTile(title: Text('Item 2')),
ListTile(title: Text('Item 3')),
// Add more grid items as needed
],
)
MOBILE APPLICATION DEVELOPMENT 52
Expanded
the Expanded widget is used to make a child widget expand to fill the available
space along the main axis of its parent widget. It's commonly used within Row,
Column, or Flex widgets to distribute available space among their children.
MOBILE APPLICATION DEVELOPMENT 53
Basic Usage:
Row(
children: <Widget>[
Container(color: Colors.red, width: 50, height: 50),
Expanded(
child: Container(color: Colors.blue),
),
Container(color: Colors.green, width: 50, height: 50),
],
)
MOBILE APPLICATION DEVELOPMENT 54
Flexible
the Flexible widget is used to make a child widget flexible within its parent's
constraints along the main axis. It's similar to the Expanded widget but offers
more flexibility in how the available space is distributed among its siblings.
MOBILE APPLICATION DEVELOPMENT 55
Basic Usage:
Row(
children: <Widget>[
Container(color: Colors.red, width: 50, height: 50),
Flexible(
flex: 2,
child: Container(color: Colors.blue),
),
Container(color: Colors.green, width: 50, height: 50),
],
)
MOBILE APPLICATION DEVELOPMENT 56
Stack
the Stack widget is used to overlay multiple widgets on top of each other. It's
commonly used for creating complex layouts where widgets need to overlap or
be positioned relative to each other or to the edges of the screen.
MOBILE APPLICATION DEVELOPMENT 57
Basic Usage:
Stack( Positioned(
top: 50,
children: <Widget>[ left: 50,
Container( child: Container(
width: 100,
width: 200, height: 100,
height: 200, color: Colors.red,
),
color: Colors.blue, ),
), ],
)
MOBILE APPLICATION DEVELOPMENT 58
Spacer
the Spacer widget is used to create flexible space within a Row or Column. It
expands to fill the available space along the main axis and can be used to
distribute space evenly between widgets.
MOBILE APPLICATION DEVELOPMENT 59
Basic Usage:
Row(
children: <Widget>[
Container(width: 50, height: 50, color: Colors.red),
Spacer(),
Container(width: 50, height: 50, color: Colors.blue),
Spacer(),
Container(width: 50, height: 50, color: Colors.green),
],
)
MOBILE APPLICATION DEVELOPMENT 60
Documentation
:
https://api.flutter.dev/flutter/material/
MOBILE APPLICATION DEVELOPMENT 61
To be
continued on
the next slide,
Thank you
MOBILE APPLICATION DEVELOPMENT 62