0% found this document useful (0 votes)
34 views43 pages

Flutter Prgs

Uploaded by

shireeshasri2004
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
34 views43 pages

Flutter Prgs

Uploaded by

shireeshasri2004
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 43

1 a) To install Flutter on Windows, follow these steps:

1. Check System Requirements

Make sure your system meets the following prerequisites:

● Operating System: Windows 7 or later (64-bit).


● Disk Space: At least 1.64 GB for the Flutter SDK (does not include disk space for IDE/tools).
● Tools: Git for Windows.
● Additional requirements for Android development:
○ Android Studio (with Android SDK).
○ Java Development Kit (JDK).

2. Download Flutter SDK

1. Go to the official Flutter website: Flutter SDK Download.


2. On the page, click the Windows tab, and download the stable Flutter SDK zip file for Windows.

3. Extract Flutter SDK

1. Once the ZIP file is downloaded, extract it to a location of your choice. For example:
○ C:\src\flutter
2. Make sure the extraction path doesn’t have spaces (e.g., avoid paths like C:\Program Files\).

4. Add Flutter to the PATH

You need to add the flutter/bin directory to your system PATH environment variable so that you can run Flutter commands from any terminal
window.

1. Open Environment Variables:


○ Right-click on This PC or Computer (depending on your version of Windows), and select Properties.
○ Click Advanced system settings on the left side.
○ Click on Environment Variables in the System Properties window.
2. Edit the Path Variable:
○ Under System Variables, scroll down and find the Path variable.
○ Click Edit, then click New.
○ Add the full path to the flutter/bin directory. For example, if you extracted Flutter to C:\src\flutter, add C:\src\flutter\bin to
the Path.
3. Click OK to save the changes and exit all windows.

5. Install Git for Windows

If you don't already have Git installed:

1. Download Git for Windows from here.


2. Run the installer and follow the installation steps, leaving most options at their defaults.

6. Verify the Installation

1. Open a Command Prompt (press Win + R, type cmd, and press Enter).

Type the following command and press Enter:


bash
Copy code
flutter doctor

2. This will check your environment and display any missing dependencies or issues. If everything is installed correctly, it should show
no issues or suggest fixes (such as installing Android Studio or configuring Android licenses).
7. Install Android Studio (For Android Development)

To develop for Android, you need to install Android Studio and the required SDKs:

1. Download and install Android Studio.


2. Launch Android Studio and follow the setup wizard to install:
○ The Android SDK.
○ Android Emulator (optional but useful for testing).
○ Android SDK Command-line tools.
3. Once Android Studio is installed, you may need to install the Flutter and Dart plugins:
○ Open Android Studio.
○ Go to File > Settings > Plugins > Marketplace.
○ Search for Flutter and click Install.
○ Do the same for the Dart plugin.
4. Restart Android Studio.

8. Run flutter doctor Again

Once you have Android Studio and all required components set up, run flutter doctor again to verify that the setup is complete. The output should
show that the Flutter SDK and Android tools are correctly configured.

9. Create Your First Flutter Project

1. Open a terminal window (Command Prompt, PowerShell, or your preferred terminal).

Run the following command to create a new Flutter project:


bash
Copy code
flutter create my_first_app

2.

Navigate to the project directory:


bash
Copy code
cd my_first_app

3.

Run the app on an emulator or connected device:


bash
Copy code
flutter run

4.

10. Install Additional Dependencies (Optional)

If you plan to use iOS development, you’ll need a macOS machine with Xcode installed. On Windows, however, you can only develop for
Android.

Troubleshooting Common Issues


Missing Dependencies: If flutter doctor reports missing dependencies (like Android licenses), run the following command:
bash
Copy code
flutter doctor --android-licenses

● Accept the licenses to proceed.

That's it! You're now set up to develop Flutter apps on Windows.

4o mini
Basic Dart Program:

import 'dart:io';
void main() {
print("enter two numbers: ");
int? x=int.parse(stdin.readLineSync()!);
int? y=int.parse(stdin.readLineSync()!);
int result;
double res;
print("MAIN MENU");
print("1. ADD");
print("2. SUBTRACTION");
print("3. MULTIPLICATION");
print("4. DIVISION");
print("5. EXIT");
print("enter your choice");
int? ch=int.parse(stdin.readLineSync()!);
while(ch!=5) {
switch (ch) {
case 1:
result = x + y;
print("the sum is $result");
break;
case 2:
result = x - y;
print("the difference is $result");
break;
case 3:
result = x * y;
print("the product is $result");
break;
case 4:
res = (x / y);
print("the division is $res");
break;
case 5:
break;
}
print("enter your choice");
ch=int.parse(stdin.readLineSync()!);
}

}
2) Explore various flutter widgets

Text Widget:

import 'package:flutter/material.dart';

void main()
{
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
//const ({super.key});

@override
Widget build(BuildContext context) {
return new MaterialApp(
home: new Scaffold(
backgroundColor: Colors.cyan,
body: new Container(
child: Padding(
padding: EdgeInsets.all(15.0),
child: Center(
child: Text(
'This is a text widget demo',
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.pink,
fontSize: 50,
),
),
),
),
),
),
);
}
}

Image Widget:

import 'package:flutter/material.dart';

void main()
{
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar:AppBar(
title: const Text(' Image Widget Demo',),
),
body: Center(
child: Column(
children:<Widget>[
Image.asset('assets/image/flutter_image.jpg', height: 400,scale:
2.5)], ), //Column
),
),
);
}
}

Container Widget:

import 'package:flutter/material.dart';

void main()
{
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Container(
padding: const EdgeInsets.all(150.0),
margin: const EdgeInsets.all(30.0),

decoration: BoxDecoration(
color: Colors.cyanAccent,
border: Border.all(width: 20, color: Colors.amber),
borderRadius: const BorderRadius.all(Radius.circular(10)),
),
child: const Text('Container Widget Demo'),
),
),
);
}
}

b) Implement Row, Column and Stack widgets

Row Widget:

import 'package:flutter/material.dart';

void main()
{
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(

appBar: AppBar(
title: Text(
"Row Widget Example"
),
),
body: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children:<Widget> [
Container(
margin: EdgeInsets.all(20.0),
padding: EdgeInsets.all(10.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5.0),
color: Colors.cyan,
),
child: Text(
"Flutter",
style: TextStyle(
color: Colors.white,
fontSize: 30,
),
),
),
Container(
margin: EdgeInsets.all(20.0),
padding: EdgeInsets.all(10.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5.0),
color: Colors.cyan,
),
child: Text(
"Devops",
style: TextStyle(
color: Colors.white,
fontSize: 30,
),
),
),
Container(
margin: EdgeInsets.all(20.0),
padding: EdgeInsets.all(10.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5.0),
color: Colors.cyan,
),
child: Text(
"Azure",
style: TextStyle(
color: Colors.white,
fontSize: 30,
),
),
),
Container(
margin: EdgeInsets.all(20.0),
padding: EdgeInsets.all(10.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5.0),
color: Colors.cyan,
),
child: Text(
"Cyber Security",
style: TextStyle(
color: Colors.white,
fontSize: 30,
),
),
),
],
),
),
);
}
}

Column Widget:

Main.dart ------------ file


import 'package:flutter/material.dart';
import 'MyApp.dart';

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

MyApp.dart-----------------file
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(

appBar: AppBar(
title: Text(
"Column Widget Example"
),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children:<Widget> [
Container(
margin: EdgeInsets.all(20.0),
padding: EdgeInsets.all(5.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5.0),
color: Colors.amber,
),
child: Text(
"Flutter",
style: TextStyle(
color: Colors.blue,
fontSize: 30,
),
),
),
Container(
margin: EdgeInsets.all(20.0),
padding: EdgeInsets.all(10.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5.0),
color: Colors.amber,
),
child: Text(
"Devops",
style: TextStyle(
color: Colors.blue,
fontSize: 30,
),
),
),
Container(
margin: EdgeInsets.all(20.0),
padding: EdgeInsets.all(10.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5.0),
color: Colors.amber,
),
child: Text(
"Azure",
style: TextStyle(
color: Colors.blue,
fontSize: 30,
),
),
),
Container(
margin: EdgeInsets.all(20.0),
padding: EdgeInsets.all(10.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5.0),
color: Colors.amber,
),
child: Text(
"Cyber Security",
style: TextStyle(
color: Colors.blue,
fontSize: 30,
),
),
),
],
),
),
);
}
}

Stack Widget

import 'package:flutter/material.dart';

void main() {
runApp(MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Stack Widget'),
backgroundColor: Colors.greenAccent[400],
), //AppBar
body: Center(
child: SizedBox(
width: 300,
height: 300,
child: Center(
child: Stack(
children: <Widget>[
Container(
width: 300,
height: 300,
color: Colors.red,
), //Container
Container(
width: 250,
height: 250,
color: Colors.black,
), //Container
Container(
height: 200,
width: 200,
color: Colors.purple,
),
Container(
width: 150,
height: 150,
color: Colors.amber,
),
Container(
width: 100,
height: 100,
color: Colors.indigoAccent,
)//Container
], //<Widget>[]
), //Stack
), //Center
), //SizedBox
) //Center
) //Scaffold
) //MaterialApp
);
}
3. a) Design a responsive UI that adapts to different screen sizes

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {


@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Responsive UI Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: ResponsiveHomePage(),
);
}
}

class ResponsiveHomePage extends StatelessWidget {


@override
Widget build(BuildContext context) {
// Get the screen width and height
double screenWidth = MediaQuery.of(context).size.width;
double screenHeight = MediaQuery.of(context).size.height;
// Define breakpoints for responsive design
if (screenWidth > 800) {
// Tablet/large screen layout
return TabletLayout();
} else if (screenWidth > 400) {
// Medium screen layout (e.g., phones in portrait mode)
return MobileLayout();
} else {
// Small screen layout (e.g., phones in portrait mode with smaller
screens)
return MobileLayout();
}
}
}

class TabletLayout extends StatelessWidget {


@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Tablet Layout'),
),
body: Padding(
padding: EdgeInsets.symmetric(horizontal: 100, vertical: 50),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
width: double.infinity,
padding: EdgeInsets.all(20),
color: Colors.blueAccent,
child: Text(
'Welcome to the Tablet Layout',
style: TextStyle(fontSize: 24, color: Colors.white),
textAlign: TextAlign.center,
),
),
SizedBox(height: 30),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ElevatedButton(
onPressed: () {},
child: Text('Button 1'),
),
ElevatedButton(
onPressed: () {},
child: Text('Button 2'),
),
],
),
],
),
),
);
}
}
class MobileLayout extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Mobile Layout'),
),
body: Padding(
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 30),
child: Column(
children: [
Container(
width: double.infinity,
padding: EdgeInsets.all(15),
color: Colors.blueAccent,
child: Text(
'Welcome to the Mobile Layout',
style: TextStyle(fontSize: 20, color: Colors.white),
textAlign: TextAlign.center,
),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {},
child: Text('Button'),
),
],
),
),
);
}
}
b) Implement media queries and breakpoints for responsiveness
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {


@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Responsive UI with Breakpoints',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: ResponsiveHomePage(),
);
}
}

class ResponsiveHomePage extends StatelessWidget {


@override
Widget build(BuildContext context) {
// Get the screen width from MediaQuery
double screenWidth = MediaQuery.of(context).size.width;
// Define breakpoints for different screen sizes
if (screenWidth > 1200) {
// Desktop or large tablet
return DesktopLayout();
} else if (screenWidth > 800) {
// Tablet layout
return TabletLayout();
} else {
// Mobile layout
return MobileLayout();
}
}
}

class DesktopLayout extends StatelessWidget {


@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Desktop Layout'),
),
body: Padding(
padding: EdgeInsets.all(50.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Welcome to the Desktop Layout',
style: TextStyle(fontSize: 32),
),
SizedBox(height: 20),
/* ElevatedButton(
onPressed: () {},
child: Text('Button 1'),
),
ElevatedButton(
onPressed: () {},
child: Text('Button 2'),
),*/
],
),
Column(
children: [
Container(
width: 300,
height: 200,
color: Colors.blueAccent,
child: Center(
child: Text(
'Some Content',
style: TextStyle(color: Colors.white, fontSize: 24),
),
),
),
],
),
],
),
),
);
}
}

class TabletLayout extends StatelessWidget {


@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Tablet Layout'),
),
body: Padding(
padding: EdgeInsets.all(20.0),
child: Column(
children: [
Text(
'Welcome to the Tablet Layout',
style: TextStyle(fontSize: 28),
),
SizedBox(height: 20),
/* ElevatedButton(
onPressed: () {},
child: Text('Button 1'),
),
ElevatedButton(
onPressed: () {},
child: Text('Button 2'),
),*/
],
),
),
);
}
}

class MobileLayout extends StatelessWidget {


@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Mobile Layout'),
),
body: Padding(
padding: EdgeInsets.all(15.0),
child: Column(
children: [
Text(
'Welcome to the Mobile Layout',
style: TextStyle(fontSize: 22),
),
SizedBox(height: 15),
/* ElevatedButton(
onPressed: () {},
child: Text('Button'),
),*/
],
),
),
);
}
}
4) Setup navigation between different screens using navigator

import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}

class MyApp extends StatelessWidget {


@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Navigator Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
initialRoute: '/',
routes: {
'/': (context) => HomePage(),
'/about': (context) => AboutScreen(),
'/dept': (context) => DeptScreen(),
},
);
}
}

class HomePage extends StatelessWidget {


@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Home Page'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Welcome to the Home Page'),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
// Navigate to the second screen
Navigator.pushNamed(context, '/about');
},
child: Text('Go to About Screen'),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
// Navigate to the third screen
Navigator.pushNamed(context, '/dept');
},
child: Text('Go to Dept Screen'),
),
],
),
),
);
}
}
class AboutScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('About Screen'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Welcome to the About Screen'),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
// Navigate back to the Home Page
Navigator.pop(context);
},
child: Text('Back to Home'),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
// Navigate to the third screen
Navigator.pushNamed(context, '/dept');
},
child: Text('Go to Dept Screen'),
),
],
),
),
);
}
}

class DeptScreen extends StatelessWidget {


@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Department Screen'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Welcome to the Dept Screen'),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
// Navigate back to the second screen
Navigator.pop(context);
},
child: Text('Back to About Screen'),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
// Navigate back to the home screen
Navigator.popUntil(context, ModalRoute.withName('/'));
},
child: Text('Back to Home'),
),
],
),
),
);
}
}
5)a) Learn about stateful and stateless widgets
In Flutter, widgets are the building blocks of your user interface (UI).
Flutter has two main types of widgets when it comes to their state management:

1. Stateless Widgets: Widgets that do not have any mutable state. Once
built, they do not change their state during the lifetime of the widget.
2. Stateful Widgets: Widgets that have mutable state. The state of the
widget can change during its lifetime, and the widget can be rebuilt to
reflect those changes.

Stateless Widgets
A StatelessWidget is a widget that doesn’t maintain any state or change over
time. Once created, the state of a StatelessWidget remains constant and is
immutable. A StatelessWidget can only depend on the information it receives
during its creation (i.e., parameters).

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {


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

class HomePage extends StatelessWidget {


@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Stateless Widget Example'),
),
body: Center(
child: Text('This is a Stateless Widget!'),
),
);
}
}
Explanation:

● MyApp is a StatelessWidget because it does not have any state that


changes after the widget is built.
● The HomePage widget is also a StatelessWidget, and it simply displays a
message on the screen.

Stateful Widgets
A StatefulWidget is a widget that can change its state over time. Stateful
widgets are used when the UI needs to update based on user interactions, data
changes, or other factors. A StatefulWidget consists of two classes:

1. StatefulWidget class: The widget itself.


2. State class: Contains the mutable state and defines the UI that is
rebuilt when the state changes

import 'package:flutter/material.dart';

void main() {

runApp(MyApp());

}
class MyApp extends StatelessWidget {

@override

Widget build(BuildContext context) {

return MaterialApp(

home: CounterPage(),

);

class CounterPage extends StatefulWidget {

@override

_CounterPageState createState() => _CounterPageState();

class _CounterPageState extends State<CounterPage> {

int _counter = 0;

// Method to increment the counter

void _incrementCounter() {

setState(() {

_counter++;

});

@override

Widget build(BuildContext context) {

return Scaffold(
appBar: AppBar(

title: Text('Stateful Widget Example'),

),

body: Center(

child: Column(

mainAxisAlignment: MainAxisAlignment.center,

children: [

Text(

'Counter Value:',

style: TextStyle(fontSize: 24),

),

Text(

'$_counter',

style: TextStyle(fontSize: 48, fontWeight: FontWeight.bold),

),

SizedBox(height: 20),

ElevatedButton(

onPressed: _incrementCounter,

child: Text('Increment Counter'),

),

],

),

),

);

}
b) implement state management using set state and provider

State management is an essential concept in Flutter to handle changes in the


state of an application and update the UI accordingly. In Flutter, there are
multiple ways to manage state, and two of the most common approaches are:

1. Using setState(): This is a simple and built-in method to manage state


within a single widget.
2. Using Provider: A more scalable and flexible state management solution
for managing state across the entire app or multiple widgets.

1. State Management with setState()

The setState() method is used to notify Flutter that the state of a widget has
changed and it needs to rebuild itself. This is the simplest state management
method and is ideal for situations where the state is only used within one
widget.

Example: Counter with setState()


import 'package:flutter/material.dart';

void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: CounterPage(),
);
}
}

class CounterPage extends StatefulWidget {


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

class _CounterPageState extends State<CounterPage> {


int _counter = 0;

// Increment the counter


void _incrementCounter() {
setState(() {
_counter++;
});
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('State Management with setState()')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Counter: $_counter',
style: TextStyle(fontSize: 36),
),
ElevatedButton(
onPressed: _incrementCounter,
child: Text('Increment'),
),
],
),
),
);
}
}

Explanation:

● The counter's state is stored in the _counter variable, and when the user
clicks the "Increment" button, the _incrementCounter() method is called.
● setState() triggers a rebuild of the CounterPage widget and updates the
displayed counter value.
● This approach works well for simple scenarios with localized state but
can become cumbersome for larger apps with more complex state changes.
2. State Management with Provider

Provider is a package that allows you to manage state across your entire app or
in specific parts of the widget tree. It separates the business logic from UI
code and makes it easier to manage app-wide state.

Step 1: Add the Provider Package

First, add the provider package to your pubspec.yaml file.

dependencies:

flutter:

sdk: flutter

provider: ^6.0.0

Run flutter pub get to install the package.

Step 2: Define a ChangeNotifier for State Management

ChangeNotifier is the base class provided by the provider package to hold and
manage state. Any widget that listens to it will be rebuilt when the state
changes.

import 'package:flutter/material.dart';

class CounterModel with ChangeNotifier {

int _counter = 0;

int get counter => _counter;

void increment() {

_counter++;

notifyListeners(); // Notify listeners to rebuild the UI

Step 3: Wrap Your App with ChangeNotifierProvider


To provide the state to the widgets below, wrap your app (or part of it) with a
ChangeNotifierProvider. This will make the CounterModel available to the widget
tree.

import 'package:flutter/material.dart';

import 'package:provider/provider.dart';

void main() {

runApp(

ChangeNotifierProvider(

create: (context) => CounterModel(),

child: MyApp(),

),

);

class MyApp extends StatelessWidget {

@override

Widget build(BuildContext context) {

return MaterialApp(

home: CounterPage(),

);

Step 4: Consume the State in the UI

Use Consumer or Provider.of to access and listen to the CounterModel. This will
allow you to rebuild the widget when the state changes.

class CounterPage extends StatelessWidget {

@override
Widget build(BuildContext context) {

return Scaffold(

appBar: AppBar(title: Text('State Management with Provider')),

body: Center(

child: Consumer<CounterModel>(

builder: (context, counterModel, child) {

return Column(

mainAxisAlignment: MainAxisAlignment.center,

children: [

Text(

'Counter: ${counterModel.counter}',

style: TextStyle(fontSize: 36),

),

ElevatedButton(

onPressed: () {

// Increment the counter using the model's method

counterModel.increment();

},

child: Text('Increment'),

),

],

);

},

),

),

);

}
Explanation:

● CounterModel is a ChangeNotifier that holds the state (counter value) and


provides an increment method to change the state.
● In the MyApp widget, we use ChangeNotifierProvider to make the
CounterModel available throughout the widget tree.
● Consumer<CounterModel> listens to changes in CounterModel and rebuilds
the part of the UI that depends on the counter value when
notifyListeners() is called in CounterModel.
● When the "Increment" button is pressed, it calls
counterModel.increment(), which updates the state and triggers the UI to
rebuild.

Key Differences Between setState() and Provider

Feature setState() Provider

Scope of State Localized to a specific Can manage global or shared


widget state across widgets

Rebuilding Rebuilds only the Rebuilds any widget that listens


Widgets widget where setState to the provider
is called

State Management Suitable for small apps Suitable for large apps with
Complexity or simple state complex state management

Performance Can cause unnecessary More efficient when combined


rebuilds in larger apps with ChangeNotifier

Code Separation State and UI are State and UI are separated,


tightly coupled making code cleaner and more
maintainable

When to Use setState() vs Provider:

● Use setState() when:


○ The state is simple and local to a specific widget.
○ You don't need to share state between multiple widgets or parts of
the app.
● Use Provider when:
○ You need to manage state that is shared across multiple widgets or
parts of the app.
○ Your app has more complex state management needs, and you want to
keep the state and UI logic separated for better maintainability.

Conclusion:

● setState() is a quick and simple way to manage state in small


applications or for local widget states. It works great when the state
only affects a single widget.
● Provider is a more scalable and flexible state management solution. It
helps to separate business logic from UI, and it’s suitable for managing
app-wide state and building large applications.

Both methods have their use cases, and you can choose the one that best fits
the complexity and scale of your app.

6)a) Create custom widgets for specific UI elements

Creating custom widgets in Flutter allows you to reuse code


efficiently and maintain a clean architecture. By building your own
widgets for specific UI elements, you encapsulate UI logic and make
your app more modular.

Here, I’ll show how to create some custom widgets for specific UI
elements in Flutter, such as a custom button, card, text field, and a
loading spinner.

1. Custom Button Widget


You might want to create a button with specific styles that you can
use across the app. Here's how you can create a reusable custom
button widget.

import 'package:flutter/material.dart';

class CustomButton extends StatelessWidget {

final String text;

final VoidCallback onPressed;


final Color color;

CustomButton({required this.text, required this.onPressed,


this.color = Colors.blue});

@override

Widget build(BuildContext context) {

return ElevatedButton(

onPressed: onPressed,

style: ElevatedButton.styleFrom(

primary: color, // Button color

padding: EdgeInsets.symmetric(vertical: 12, horizontal: 24),


// Padding

shape: RoundedRectangleBorder(

borderRadius: BorderRadius.circular(8), // Rounded corners

),

),

child: Text(

text,

style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),

),

);

Usage:

CustomButton(
text: "Click Me",

onPressed: () {

print("Button Pressed!");

},

2. Custom Card Widget


If you want a reusable card with specific styling, you can create a
custom card widget that can be reused across different screens in
your app.

class CustomCard extends StatelessWidget {

final String title;

final String description;

final IconData icon;

CustomCard({

required this.title,

required this.description,

required this.icon,

});

@override

Widget build(BuildContext context) {

return Card(

elevation: 4.0,

shape: RoundedRectangleBorder(

borderRadius: BorderRadius.circular(12), // Rounded corners

),
child: Padding(

padding: const EdgeInsets.all(16.0),

child: Row(

children: [

Icon(

icon,

size: 40,

color: Colors.blue,

),

SizedBox(width: 16),

Expanded(

child: Column(

crossAxisAlignment: CrossAxisAlignment.start,

children: [

Text(

title,

style: TextStyle(fontSize: 18, fontWeight:


FontWeight.bold),

),

SizedBox(height: 8),

Text(

description,

style: TextStyle(fontSize: 14, color:


Colors.grey),

),

],

),
),

],

),

),

);

Usage:

CustomCard(

title: "Card Title",

description: "This is a custom card description",

icon: Icons.info,

3. Custom TextField Widget


If you want a reusable text field with some common styling, you can
create a custom widget for that as well.

class CustomTextField extends StatelessWidget {

final String hintText;

final TextEditingController controller;

final TextInputType inputType;

final bool obscureText;

CustomTextField({

required this.hintText,

required this.controller,
this.inputType = TextInputType.text,

this.obscureText = false,

});

@override

Widget build(BuildContext context) {

return TextField(

controller: controller,

keyboardType: inputType,

obscureText: obscureText,

decoration: InputDecoration(

labelText: hintText,

border: OutlineInputBorder(

borderRadius: BorderRadius.circular(12), // Rounded corners

),

contentPadding: EdgeInsets.symmetric(vertical: 10,


horizontal: 16), // Padding inside text field

),

);

Usage:

TextEditingController _controller = TextEditingController();

CustomTextField(
hintText: "Enter your username",

controller: _controller,

4. Custom Loading Spinner Widget


A reusable loading spinner widget is essential for showing a loading
indicator in your app. You can create a custom widget for this.

class CustomLoader extends StatelessWidget {

final String message;

CustomLoader({this.message = "Loading..."});

@override

Widget build(BuildContext context) {

return Center(

child: Column(

mainAxisAlignment: MainAxisAlignment.center,

children: [

CircularProgressIndicator(),

SizedBox(height: 16),

Text(

message,

style: TextStyle(fontSize: 16, fontWeight:


FontWeight.w500),

),

],

),

);
}

Usage:

CustomLoader(message: "Please wait...")

5. Custom Avatar Widget


If your app frequently displays user avatars or profile pictures, you
can create a reusable custom avatar widget.

class CustomAvatar extends StatelessWidget {

final String imageUrl;

final double radius;

CustomAvatar({required this.imageUrl, this.radius = 30.0});

@override

Widget build(BuildContext context) {

return CircleAvatar(

radius: radius,

backgroundImage: NetworkImage(imageUrl), // URL for the image

onBackgroundImageError: (exception, stackTrace) {

// Handle any error if image fails to load

},

);

}
Usage:

CustomAvatar(imageUrl: "https://example.com/avatar.jpg")

7)b) Applying styling using themes and custom style

You might also like