0% found this document useful (0 votes)
18 views

Flutter Tutorial

Uploaded by

subhamansha11
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
18 views

Flutter Tutorial

Uploaded by

subhamansha11
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 19

Flutter

I’ll walk you through the basics of Flutter from the ground up. By the end, you'll
have a solid understanding of Flutter’s core concepts and be ready to start
building your own apps. Here’s a simple and structured guide:

1. What is Flutter?
Flutter is a UI toolkit developed by Google to build natively compiled
applications for mobile, web, and desktop from a single codebase. It uses the
Dart programming language.

2. Setting Up Flutter
Before coding, let’s set up the Flutter environment.

Steps to Set Up Flutter:


1. Install Flutter:

Download Flutter SDK from here.

Extract the Flutter SDK to your desired location.

Add the Flutter bin directory to your system’s PATH to access the flutter

command from the terminal.

2. Set Up IDE:

You can use Visual Studio Code or Android Studio.

Install the Flutter and Dart extensions in your IDE for a smooth coding
experience.

3. Check Setup:

Open your terminal and type:

bash
Copy code
flutter doctor

Flutter 1
This checks if Flutter is set up correctly and tells you what’s missing
(like SDKs, device setup, etc.).

3. Understanding the Project Structure


After creating your first Flutter project ( flutter create my_app ), here's what the
folder structure will look like:

android/, ios/, web/: Platform-specific code and settings.

lib/: Your main app logic goes here.

main.dart: The entry point of your app.

pubspec.yaml: Configuration file where you add dependencies (libraries),


app name, icons, and fonts.

4. Basic Flutter Concepts


Let’s cover some basic concepts to get you started.

Widgets
Flutter is all about widgets. Everything in Flutter is a widget, from the layout
(columns, rows) to UI elements (buttons, text).
There are two types of widgets:

StatelessWidget: Doesn’t change once created (immutable).

StatefulWidget: Can change over time (like user interactions).

5. Writing Your First App


Let’s dive into code and build a simple app that displays "Hello, Flutter!" on the
screen.

Step-by-step code for a basic Flutter app:


1. Open lib/main.dart (this is your main file).

2. Replace the code with:

dart
Copy code
import 'package:flutter/material.dart';

Flutter 2
void main() {
runApp(MyApp());
}

class MyApp extends StatelessWidget {


@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Hello Flutter'),
),
body: Center(
child: Text('Hello, Flutter!', style: TextStyl
e(fontSize: 24)),
),
),
);
}
}

Explanation of the Code:


main(): This is the entry point of every Dart app.

MyApp: A custom widget that extends StatelessWidget.

MaterialApp: A wrapper that sets up navigation, themes, etc.

Scaffold: Provides a basic structure (like app bar, body).

AppBar: The top bar with the title "Hello Flutter".

Center: Centers the child widget (in this case, the text).

Text: Displays "Hello, Flutter!" with a font size of 24.

6. Adding Interactivity (Stateful Widgets)


Now let’s add a button that changes the displayed text when pressed.

Flutter 3
Step-by-step code for adding a button:
1. Replace the MyApp widget with this StatefulWidget:

dart
Copy code
import 'package:flutter/material.dart';

void main() {
runApp(MyApp());
}

class MyApp extends StatelessWidget {


@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Stateful Widget Example'),
),
body: MyHomePage(),
),
);
}
}

class MyHomePage extends StatefulWidget {


@override
_MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {


String displayText = "Hello, Flutter!";

void _changeText() {
setState(() {
displayText = "You pressed the button!";
});
}

Flutter 4
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
displayText,
style: TextStyle(fontSize: 24),
),
SizedBox(height: 20), // Adds spacing between
widgets
ElevatedButton(
onPressed: _changeText,
child: Text('Press me'),
),
],
),
);
}
}

Explanation of the Code:


StatefulWidget: Allows the app’s state to change when the button is
pressed.

setState(): Notifies Flutter to rebuild the UI when the state changes.

ElevatedButton: A material design button widget. It triggers _changeText

when pressed.

7. Basic Flutter Layouts


Here are some common widgets for layout building:

Row and Column


Row: Arranges widgets horizontally.

Flutter 5
Column: Arranges widgets vertically.

Example:

dart
Copy code
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Hello, World!'),
Text('Welcome to Flutter!'),
],
)

Padding and Containers


Padding: Adds space around a widget.

Container: A versatile widget to add padding, color, size, etc.

Example:

dart
Copy code
Container(
padding: EdgeInsets.all(16.0),
color: Colors.blue,
child: Text('Hello with Padding'),
)

SizedBox
SizedBox: Creates a box with a specific size.

Example:

dart
Copy code

Flutter 6
SizedBox(height: 20) // Adds vertical spacing

8. Navigating Between Screens


In a real app, you'll often want to navigate between screens (or pages).

1. Create a new screen ( lib/second_screen.dart ):

dart
Copy code
import 'package:flutter/material.dart';

class SecondScreen extends StatelessWidget {


@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Second Screen'),
),
body: Center(
child: Text('Welcome to the second screen!'),
),
);
}
}

2. Modify lib/main.dart to navigate:

dart
Copy code
import 'package:flutter/material.dart';
import 'second_screen.dart'; // Import the new screen

void main() {
runApp(MyApp());
}

Flutter 7
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Navigation Example'),
),
body: MyHomePage(),
),
);
}
}

class MyHomePage extends StatelessWidget {


@override
Widget build(BuildContext context) {
return Center(
child: ElevatedButton(
onPressed: () {
// Navigate to the second screen
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Seco
ndScreen()),
);
},
child: Text('Go to Second Screen'),
),
);
}
}

Explanation:
Navigator.push(): Pushes a new route (or screen) on the navigation stack.

MaterialPageRoute: A page route that transitions to a new screen.

Flutter 8
9. Understanding pubspec.yaml and Dependencies
In pubspec.yaml , you can:

Add external libraries.

Define app name, version, and assets (like images and fonts).

Example: Adding a library (like http for API calls)


1. In pubspec.yaml :

yaml
Copy code
dependencies:
flutter:
sdk: flutter
http: latest_version

2. Run:

bash
Copy code
flutter pub get

10. Next Steps


Now that you have the basics of Flutter down, here’s what you can do next:

1. Learn More Widgets: Explore Flutter’s widget catalog.

2. Handling User Input: Learn about forms and user input using TextField and
Form widgets.

3. APIs and HTTP: Fetch data from the internet using the http package.

4. Firebase Integration: Add Firebase for authentication, database, etc.

5. State Management: Learn about different state management techniques


like Provider or Riverpod .

Flutter 9
That's a simple guide to get you started on Flutter. Let me know if you want to
dive deeper into any of these topics!

Now that you've mastered the basics of Flutter and have started building apps,
let's take your skills to the intermediate level. This guide will help you go
deeper into Flutter concepts, introduce important architectural patterns,
advanced widgets, and more. Here’s a detailed breakdown of next steps to
become an intermediate Flutter developer.

1. State Management (Intermediate Concepts)


In complex applications, managing the state becomes crucial. As an
intermediate Flutter developer, you need to understand and choose the right
state management solution.

Common State Management Solutions:


1. setState() : Suitable for simple state changes (you've already used this).

2. InheritedWidget : A low-level way to share data across widgets.

3. Provider(Most recommended): A wrapper over InheritedWidget for simpler


state management.

4. Riverpod : An advanced alternative to Provider.

5. Bloc/Cubit: Implements the BLoC (Business Logic Component) pattern,


especially for event-driven state.

Using Provider (Common Choice):


Let’s start with Provider, which is widely used for managing state in Flutter
apps.

Step-by-step guide to using Provider:


1. Add Provider to pubspec.yaml :

yaml
Copy code

Flutter 10
dependencies:
provider: latest_version

2. Simple Example using Provider:

dart
Copy code
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() {
runApp(
ChangeNotifierProvider(
create: (context) => Counter(),
child: MyApp(),
),
);
}

class MyApp extends StatelessWidget {


@override
Widget build(BuildContext context) {
return MaterialApp(
home: CounterScreen(),
);
}
}

class CounterScreen extends StatelessWidget {


@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Counter with Provider'),
),
body: Center(
child: Column(

Flutter 11
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many time
s:',
),
Text(
'${Provider.of<Counter>(context).count}',
style: Theme.of(context).textTheme.headlin
e4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Provider.of<Counter>(context, listen: false).i
ncrement();
},
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}

class Counter extends ChangeNotifier {


int _count = 0;

int get count => _count;

void increment() {
_count++;
notifyListeners(); // Notifies widgets to rebuild
}
}

Flutter 12
Explanation:
Provider allows you to share state between widgets without passing the
state manually.

ChangeNotifier is a class that your model (state) can extend, allowing the
state to notify its listeners when something changes.

ChangeNotifierProvider: Wraps the app with the provider so that any


widget can access the shared state.

2. Advanced Navigation (Named Routes & Deep Links)


When your app scales, managing multiple screens becomes more complex.
Flutter provides various ways to handle navigation.

Using Named Routes:


1. Define Routes in MaterialApp :

dart
Copy code
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {


@override
Widget build(BuildContext context) {
return MaterialApp(
initialRoute: '/',
routes: {
'/': (context) => HomeScreen(),
'/second': (context) => SecondScreen(),
},
);
}
}

class HomeScreen extends StatelessWidget {


@override

Flutter 13
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Home Screen'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, '/second');
},
child: Text('Go to Second Screen'),
),
),
);
}
}

class SecondScreen extends StatelessWidget {


@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Second Screen'),
),
body: Center(
child: Text('Welcome to the Second Screen!'),
),
);
}
}

2. Explanation:

initialRoute: Defines the default route (home screen).

routes: A map of route names to corresponding screen widgets.

Navigator.pushNamed(): Used to navigate between named routes.

Flutter 14
Deep Linking:
To handle URLs that open your app at specific screens, you need to work with
deep links. Here’s a guide on deep linking in Flutter.

3. Networking (API Calls)


Fetching data from the web is a crucial part of most apps. You’ll commonly use
REST APIs to get or send data.

Using the http package:


1. Add http to pubspec.yaml :

yaml
Copy code
dependencies:
http: latest_version

2. Fetch Data from an API:

dart
Copy code
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {


@override
Widget build(BuildContext context) {
return MaterialApp(
home: JsonDataScreen(),
);
}
}

class JsonDataScreen extends StatefulWidget {

Flutter 15
@override
_JsonDataScreenState createState() => _JsonDataScreenS
tate();
}

class _JsonDataScreenState extends State<JsonDataScreen>


{
List data;

Future<void> fetchData() async {


final response = await http.get(Uri.parse('https://j
sonplaceholder.typicode.com/posts'));

if (response.statusCode == 200) {
setState(() {
data = json.decode(response.body);
});
} else {
throw Exception('Failed to load data');
}
}

@override
void initState() {
super.initState();
fetchData();
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Fetch JSON Data'),
),
body: data == null
? Center(child: CircularProgressIndicator())
: ListView.builder(
itemCount: data.length,

Flutter 16
itemBuilder: (context, index) {
return ListTile(
title: Text(data[index]['title']),
subtitle: Text(data[index]['body']),
);
},
),
);
}
}

Explanation:
The app fetches a list of posts from an API
( https://jsonplaceholder.typicode.com/posts ).

http.get() fetches data from the API.

The JSON response is decoded using json.decode() , and the data is


displayed using a ListView.builder() .

4. Forms and Input Validation


Handling user input is essential for most applications. You will often deal with
forms, text fields, and validation.

Building a Form with Validation:


1. Code Example:

dart
Copy code
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {


@override
Widget build(BuildContext context) {
return MaterialApp(

Flutter 17
home: FormScreen(),
);
}
}

class FormScreen extends StatefulWidget {


@override
_FormScreenState createState() => _FormScreenState();
}

class _FormScreenState extends State<FormScreen> {


final _formKey = GlobalKey<FormState>();

String _email;

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Form Validation'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Form(
key: _formKey,
child: Column(
children: <Widget>[
TextFormField(
decoration: InputDecoration(labelText:
'Email'),
validator: (value) {
if (value.isEmpty) {
return 'Please enter an email';
} else if (!RegExp(r'^[^@]+@[^@]+\.[^
@]+').hasMatch(value)) {
return 'Enter a valid email';
}
return null;

Flutter 18
},
onSaved: (value) {
_email = value;
},
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
if (_formKey.currentState.validate())
{
_formKey.currentState.save();
ScaffoldMessenger.of(context).showSn
ackBar(SnackBar(
content: Text('Form Submitted: $_e
mail'),
));
}
},
child: Text('Submit'),
),
],
),
),
),
);
}
}

Explanation:
Form: Holds a group of form fields. It needs a GlobalKey to identify the form.

TextFormField: A text input field with validation.

validator: Checks

Flutter 19

You might also like