0% found this document useful (0 votes)
22 views96 pages

Flutter Development Course Overview

The document outlines a Flutter course by Fahmi Zouari for the 2023-2024 academic year, covering topics such as the basics of Dart, widgets, web service consumption, and Firebase Cloud Firestore. It introduces Flutter as a cross-platform UI framework and Dart as its programming language, detailing various types of applications and their advantages and disadvantages. The course includes practical examples and explanations of widgets, control structures, and user interface components in Flutter.
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)
22 views96 pages

Flutter Development Course Overview

The document outlines a Flutter course by Fahmi Zouari for the 2023-2024 academic year, covering topics such as the basics of Dart, widgets, web service consumption, and Firebase Cloud Firestore. It introduces Flutter as a cross-platform UI framework and Dart as its programming language, detailing various types of applications and their advantages and disadvantages. The course includes practical examples and explanations of widgets, control structures, and user interface components in Flutter.
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

Flutter Course By Fahmi ZOUARI

2023-2024
PLAN
Introduction to Flutter

The basics of Dart

Introduction to widgets

Examples of widgets

The roads

Consumption of web services

Firebase Cloud Firestore


Introduction
to Flutter
What is Flutter?

• Flutter is an open source user interface framework from Google.


• Flutter allowing the creation of high-quality applications on iOS, Android, Web,
Office and Embedded from a single codebase.
• Flutter allows creating cross-platform applications compiled natively.
• The first version of Flutter was released on December 4, 2018.
• In version 2.0.0 of Flutter, several bugs and issues have been resolved, furthermore the
The web version is now classified as stable. This version was released on May 6.
2021.

4
What is Dart?

• Dart is a programming language for cross-platform applications.


• Developed by Google.
• Dart is an object-oriented language.
• Dart compiles to native code.

5
Technologies
Native applications
Android iOS
Java Objective-C
Kotlin (2017) ▸ Swift (2014)

Advantages Disadvantages
Performances 1 application per platform
Specific interface for Costs and development time
each platform

7
Applications hybrides

Cordova, Ionic, ...


Based on web technologies (HTML, JS, CSS, ...)
▸ Use WebView (integrated web browser)

Advantages Disadvantages
Shared code Performances
Reuse
Security

8
Cross-platform applications
• Examples of frameworks: React Native, Xamarin, Flutter
• Objective: to generate 1 Android and iOS application from the same code

Advantages Disadvantages
• Shared code / reuse • May require writing code
• Performances specific

9
A few
numbers
Google Trends

[Link]

11
Stack Overflow Trends

Source:[Link]
12
Installation of the environment

[Link]

13
Thebasicsof
Dart
Naming conventions

• snake_case (e.g. "home_screen.dart")


File names
• UpperCamelCase (e.g., 'HomeScreen')
Classes
Builders
• lowerCamelCase (e.g.: "toJson" )
Methods
Variables
Constants

15
Types in Dart
• Everything that is placed in a variable is an object, including 'int' and 'double' types.
{"bool":"bool","null":"null"}

int a = 5;

• If you do not specify a type for a variable, Dart will


automatically deduct it
vara =5;

• The type 'dynamic' is equivalent to any type.

dynamica =5;
a = "toto";

16
Lists and maps
• List: • Map:
No type 'Array' in Dart

Map<String, int> map1 = Map();


List<int> list1 = List();
Map<String, int> map2 = {'var1':1,'var2':2};
List<int> list2 = [];
List<int> list3 = [1,2,3]; print(map2['var1']); // Displays 1
Map<String,dynamic> map3 = Map();
List<dynamic> liste4 = [1,'Hello',3.3];
List list5 = [4, "my list"]; map3['toto'] ='titi';

print(liste3[0]); Display 1 map3['tata'] =3;

[Link](4); Map map4 = Map(); // <=> Map<dynamic, dynamic>


print([Link]); // Affiche 4
map4['toto'] ='titi';
map4[4] = 8;
print(map4[4]); // Displays 8

17
Map<String, int> map1 = Map();
Map<String, int> map2 = {'var1':1,'var2':2};
print(map2['var1']); // Displays 1
Map<String,dynamic> map3 = Map();
map3['toto'] ='titi';

map3['tata'] =3;

Map map4 = Map();// <=> Map<dynamic, dynamic>


map4['toto'] ='titi';
map4[4] = 8;
print(map4[4]);// Displays 8
18
Control structures
if(age < 14)
Children
}else if(age<24)
Adolescents

else {
Adults
}

bool isPublic = true;


String visibility = isPublic ?'public':'private';

19
The loops
List<String> students = ['s1','s2','s3'];
for(var student in students) {
print(student);
}

for(i = 0; i < [Link]; i++) {


print(students[i]);
}

while(year < 2016) {


year += 1;
}

// foreach((String)→void f)→void

[Link]((student) {
print(student);
});

[Link]().forEach((index, student)
{
$index:$student
});
20
Functions
int sum(int a, int b) {
return a + b;
}

int sum([int a=0, int b=0]) {


return a + b;
}

int s = sum(1, 2);

int sum({required int a, required int b}) {


return a + b;
}

int s = sum(a:1, b:2);

21
The classes
class Person {
Stringname;
Person([Link]);
}

Person(String name) {
[Link] = name;
}

Personp=Person("toto");

22
Introduction
tothewidgets
What is a widget?

•In Flutter, everything is a widget!


•The main role of a widget is to make a
rendered via the "build()" method
•Widgets are organized in the form
of the hierarchy
•The method 'runApp' accepts only
a Widget type as a parameter

24
Stateless widgets

• No state
• Contains only one method: "Widget
build(BuildContext context)
• Cannot be 're-builder' by itself
• Life cycle:
• Initialization
• Rendering (build() method)

25
Stateless widgets

class MyApp extends StatelessWidget {


@override
Widget build(BuildContext context) {
returnContainer();
}
}

26
Stateful widgets

• Contains a state
• The 'build()' method is relocated to the state.
• A single method: "State<T> createState()" where
<T> corresponds to the StatefulWidget class
• The 'build' method is called each time
modification of the state
• State = set of attributes of the State class
• "initState()" : méthode pour initialisation le state

27
Stateful Widgets

• Behaves a state
• The 'build()' method is moved to the state.
• A single method: "State<T> createState()" where
T corresponds to the StatefulWidget class
• Method "build" called on each modification of the
state
• State = set of attributes of the class State
• "initState()" : méthode pour initialisation le state

28
Stateful widgets
class MyApp extends StatefulWidget {

@override
_MyAppState createState() =>
MyAppState();
}

class MyAppState extends State<MyApp> {


lateint_counter;

@override
voidinitState() {
_counter=0;
[Link]();
}

@override
Widget build(BuildContext context) {
returnText("Compteur$_counter");
}
}

29
The Text widget

Text(
"Compteur$_counter",
style:TextStyle(
fontWeight: [Link],
fontSize:16,
color: [Link],
),
);

30
The Image widget
[Link]
assets:
assets/image/

Center
child:[Link]("assets/image/
my_image.jpg
)

[Link]('[Link]

31
The Scaffold widget
Scaffold
appBar: AppBar(
title:Text("My app"),
),
body:Center(
child:Text("Home page"),
),
floatingActionButton:FloatingActionButton(
onPressed: () {
clicked
},
child:Icon([Link]),
),
bottomNavigationBar:BottomNavigationBar(
items: [
BottomNavigationBarItem(
label:"home",
icon:Icon([Link])
),
BottomNavigationBarItem
label:"calendar",
icon:Icon(Icons.calendar_today)
),
BottomNavigationBarItem(
label:"contact",
icon:Icon(Icons.contact_mail)
),
],
),
) 32
Thewidgets
ofthelayout
The widget container

Center(
child:Container(
height:100,
width:200
color: [Link],
margin: [Link](20),
child:Center(
child:Text("Home page")
),
),
)

34
The widget padding
Center(
child:Container(
height:100,
width:200,
color: [Link],
margin: [Link](20),
child:Padding(
padding: const [Link](8.0),
child:Container(
color: [Link],
child:Center(
child:Text("Home page")
),
),
),
),
)

35
The column widget
SingleChildScrollView
child:Column(
Container
children: [
height:100,
Container
color: [Link][400],
height:100,
),
color: [Link][900],
Container
),
height:100,
Container
color: [Link][300],
height:100,
),
color: [Link][800],
Container
),
height:100,
Container
color: [Link][200],
height:100,
),
color: [Link][700],
Container
),
height:100,
Container
color: [Link][100],
height:100,
),
color: [Link][600],
),
],
Container
),
height:100,
),
color: [Link][500],
),

36
The column widget

37
The widget row
SingleChildScrollView(
scrollDirection: [Link],
child:Row(
children: [
Container
width:100
height:100,
color: [Link][900],
),
Container
width:100,
height:100,
color: [Link][800],
),
Container
width:100,
height:100,
color: [Link][700],
),
Container
width:100,
height:100,
color: [Link][600],
),
Container
width:100,
height:100, 38
color: [Link][500],
The widget row

39
The ListTile widget

ListTile
leading:FlutterLogo(size:56.0),
title:Text('Two-line ListTile'),
subtitle:Text('Here is a second
line'
trailing: Icon(Icons.more_vert),
)

40
Widgets
relatedto
lists
The ListView widget
ListView(
children: [
Container(
width:100,
height:100,
color: [Link][900],
),
Container
width:100
height:100,
color: [Link][800],
),
Container(
width:100,
height:100,
color: [Link][700],
),
Container
width:100,
height:100,
color: [Link][600],
),
],
)

42
The ListTile widget
ListView(
children: [
ListTile
leading:Icon(Icons.supervised_user_circle),
title:Text("my name"),
subtitle:Text("my job"),
trailing:Icon([Link]),
),
ListTile
leading:Icon(Icons.supervised_user_circle),
title:Text("my name"),
subtitle:Text("my job"),
trailing: Icon([Link]),
),
ListTile
leading:Icon(Icons.supervised_user_circle),
title:Text("my name"),
subtitle:Text("my job"),
trailing:Icon([Link]),
),
],
)

43
Thewidgets
Information
Card
Card
child:Column(
mainAxisSize: [Link],
children: <Widget>[
constListTile
leading:Icon([Link]),
title:Text('The Enchanted Nightingale'),
subtitle:Text('Music by Julie Gable. Lyrics by
Sidney Stein.
),
Row(
mainAxisAlignment: [Link],
children: <Widget>[
TextButton
child:constText('BUY TICKETS'),
onPressed: () {/* ... */},
),
constSizedBox(width:8)
TextButton(
child:constText('LISTEN'),
onPressed: () {/* ... */},
),
constSizedBox(width: 8),
],
),
],
),
45
)
Progress Indicator

Column
mainAxisAlignment:
[Link],
children: [
CircularProgressIndicator()
SizedBox(height:50,),
Linear Progress Indicator()
],
)

46
Tooltip
Tooltip(
message:'I am a Tooltip',
decoration:BoxDecoration(
borderRadius:[Link](25),
gradient:
LinearGradient
colors: <Color>[
[Link].shade900
[Link][400]!
]
),
),
height:50,
padding: const [Link](8.0)
preferBelow:true,
textStyle:constTextStyle(
fontSize:24,
color: [Link]
),
showDuration:Duration(seconds:3),
Hover over the text to show a
tooltip.'),
)

47
AlertDialog
Future<void> _showMyDialog() async {
returnshowDialog<void>(
context:context
barrierDismissible:false,// user must tap button!
builder: (BuildContext context) {
returnAlertDialog(
title:constText('AlertDialog Title'),
content:SingleChildScrollView(
child:ListBody(
children:const<Widget>[
This is a demo alert dialog.
Would you like to approve of this
message?
],
),
),
actions: <Widget>[
TextButton(
child:constText('Approve'),
onPressed: () {
[Link](context).pop();
},
),
],
);
},
);
48
}
Widgets
ofInputandof
selection
TextField
TextField(
decoration:InputDecoration(
border: OutlineInputBorder(
borderRadius:
[Link]([Link](10.0))
),
focusedBorder:OutlineInputBorder(
borderSide:BorderSide(color: [Link]),
borderRadius:
[Link]([Link](10.0))
),
hintText:"your text",
label:Text("label"),
fillColor: Colors.white70
),
)

border:
UnderlineInputBorder()

50
TextField
TextField(
obscureText:true,
decoration:InputDecoration(
border:OutlineInputBorder(),
labelText:'Password',
),
),

TextEditingController controller = TextEditingController();

TextField(
controller:controller,
obscureText:true,
decoration:InputDecoration(
border: OutlineInputBorder(),
labelText:'Password',
),
),
51
Form
final_formKey=
GlobalKey<FormState>();

Form
key:_formKey,
child:Column(
children: [],
)
)
TextFormField(
ElevatedButton(
decoration:constInputDecoration(
onPressed: () {
border:OutlineInputBorder(),
if(_formKey.currentState!.validate()) {
labelText:'Email',
[Link](context).showSnackBar(
hintText:'Enter Email'
const SnackBar(content: Text('Processing')
),
Data
autovalidateMode:
);
}
[Link]
},
validator: (value) {
child:constText('Submit'),
if(value!.isEmpty) { )
* Required
}else if(![Link]())
{
Check your email
}else
return null;
}, 52
)
Form
Form if(value!.isEmpty) {
key:_formKey, * Required
child:Column( }else if([Link]<6) {
children: <Widget>[ Password should be at least 6
TextFormField characters
decoration:constInputDecoration( }else if([Link]>15) {
border:OutlineInputBorder(), Password should not be
labelText:'Email', greater than 15 characters
hintText:'Enter Email' else
), return null;
validator: (value) { },
if(value!.isEmpty) { ),
* Required constSizedBox(height:16,),
}else if(![Link]()) { ElevatedButton(
Check your email onPressed: () {
else if (_formKey.currentState!.validate())
return null; {
},
), [Link](context).showSnackBar(
const SizedBox(height: 16,) constSnackBar(content:
TextFormField Processing Data
decoration:constInputDecoration( );
border: OutlineInputBorder(), }
labelText:'Password', },
hintText:'Enter secure password' child:constText('Submit'),
), )
obscureText:true, ],
validator: (value) { ), 53
Form

54
Checkbox

Row(
children: [
Checkbox(
checkColor: [Link],
value:isChecked,
onChanged: (bool? value) {
setState(() {
isChecked= value!;
});
},
),
constText("label")
],
),

55
Radio
group 1 group 2
ListTile ListTile
title:constText('A'), title:constText('C'),
leading:Radio<String>( leading:Radio<String>(
value:"a", value:"c",
groupValue:_character, groupValue:_character2,
onChanged: (String? value) { onChanged: (String? value) {
ListTile
setState(() { setState(() {
title:constText('E'),
_character= value!; _character2= value!; leading:Radio<String>(
}); });
value:"e",
}, },
groupValue:_character2,
), ),
onChanged: (String? value) {
), ),
setState(() {
ListTile ListTile
_character2= value!;
title:constText('B'), title:constText('D'),
});
leading:Radio<String>( leading:Radio<String>(
},
value:"b", value:"d",
),
groupValue:_character, groupValue:_character2,
),
onChanged: (String? value) { onChanged: (String? value) {
setState(() { setState(() {
_character= value!; _character2= value!;
}); });
}, },
), ),
), ),

56
Thewidgets
ofButton
ElevatedButton and OutlinedButton
ElevatedButton
onPressed: () {},
style: [Link](
shape:RoundedRectangleBorder(
borderRadius:[Link](30.0),
),
),
child:constText(' Elevated Button', style:TextStyle(fontSize:
18),)
),
constSizedBox(height:12,)
ElevatedButton
onPressed: () {},
Elevated Button
18),)
),

OutlinedButton
onPressed: () {
debugPrint('Received click');
},
child:constText('Click Me'),
)

58
FloatingActionButton and IconButton
const SizedBox(height: 12),
FloatingActionButton
onPressed: () {},
child:const
Icon([Link])
),
constSizedBox(height:12,)
[Link](
onPressed: () {},
label:constText("image"),
icon:constIcon([Link]),
),

IconButton(
onPressed: () {},
icon:constIcon([Link])
),

59
TextButton and InkWell
TextButton(
style: [Link](
textStyle:constTextStyle(fontSize:
20)
),
onPressed: () {},
child:constText('Text'),
)

InkWell(
onTap: () {},
child:const
Text
)

InkWell
onTap: () {},
child:Container(
color: [Link],
child:constText(
Text
TextStyle(color: [Link])
)
)
) 60
Theroads
Navigation to a new page
ElevatedButton
onPressed: () {
[Link](
context
MaterialPageRoute
builder: (context) => SecondRoute()),
);
},
child:constText("click")
)

62
Navigation with named routes
MaterialApp(
title:'Named Routes Demo',
initialRoute:'/',
routes: {
'/': (context) =>constFirstScreen(),widget.
'/second': (context) =>constSecondScreen(),
},
)
)

ElevatedButton(
onPressed: () {
[Link](context,
/second
},
child:constText("click")
)

63
Return to the previous page

ElevatedButton
onPressed: () {
[Link](context);
},
child:constText("Back")
)

64
Data transfer between Widgets
Named routes
Send
[Link](context).pushNamed("/second", arguments:"argument
1

Recover
finalargs =
[Link](context)!.[Link];

Unnamed routes
Send Recover Access StatefulWidget
class MyWidget extends StatefulWidget {
MyWidget( Stringparam1; Text(
param1:"text 1", Stringparam2; widget.param1
param2:"Text 2", MyWidget({ )
)
required this.param1
required this.param2
Access StatelessWidget
});
@override Text(
_MyWidgetState createState() => param1
_MyWidgetState(); )
65
}
Consumption
webs
services
Architecture
API

[Link]
Model Service

[Link]

Interface

67
Architecture

modelsservices pages global_widgets

[Link] [Link] login [Link]


[Link] [Link]
user_se [Link]
app_sc
[Link]
[Link] affold.d
rt
rt local_widgets art
logic
logic
login
login. he
dart ader
.dart

home 68
Model classArticle {
Article({
[Link]
[Link],
[Link],
[Link],
[Link],
[Link],
[Link],
[Link]
});

finalSource?source;
finalString?author;
finalString?title;
finalString?description;
finalString?url;
finalString?urlToImage;
finalDateTime?publishedAt;
finalString?content;
}
69
Model
[Link](Map<String,dynamic> json) =>Article(
source: json["source"] == null ?
null:
[Link](json["source"]),
author: json["author"] ==null?null: json["author"],
title: json["title"] ==null?null: json["title"],
description: json["description"] ==null?
null:
json["description"],
url: json["url"] ==null?null: json["url"],
urlToImage: json["urlToImage"] ==null?
null:
json["urlToImage"],
publishedAt: json["publishedAt"] ==null?
null:
[Link](json["publishedAt"]),
content: json["content"] ==null?null: json["content"],
);
70
Model
Map<String,dynamic> toJson() => {
"source":source==null?null:source!.toJson(),
"author":author==null?null:author,
"title":title==null?null:title,
"description":description==null?null:description,
"url":url==null?null:url,
"urlToImage":urlToImage==null?null:urlToImage,
"publishedAt":publishedAt==null?
null:
publishedAt!.toIso8601String()
"content":content==null?null:content,
};

71
Model
Data dataFromJson(String str) =>[Link]([Link](str));

String dataToJson(Data data) => [Link]([Link]());

72
service
install the dependency

[Link]
http

[Link]
dependencies:
run
http: ^0.13.4 flutter pub get

import 'package:http/[Link]' as
http;

73
service
classNewsService{
Future<Data> getAll() async {
varurl = [Link]([Link]
country=us&category=business&apiKey=e0ac43cc665a48aeb762ed7dae8139e9'
);
varresponse = await [Link](url);
print('Response status:${[Link]}');
print('Response body:${[Link]}');
return data from json([Link]);
}
}
Map<String, String> queryParameters = {
"country":"us",
"category":"business",
"apiKey":
e0ac43cc665a48aeb762ed7dae8139e9
};
varurl = Uri(
scheme:'https',
host:'[Link]',
path:'/v2/top-headlines',
queryParameters: queryParameters,
74
);
Interface

NewsServicenewsService=NewsService();

[Link]().then((value) {
print([Link]!.[Link]);
});

OR

Data data = await [Link]();

75
Interface
NewsService newsService = NewsService();

FutureBuilder(
future:[Link]()
builder: (BuildContext context, AsyncSnapshot snapshot) {
if([Link]) {
returnOnSuccess(
data: [Link],
);
} else if ([Link]) {
returnOnError(
error: [Link](),
);
else {
return constWaiting();
}
},
) 76
Interface
class OnError extends StatelessWidget {
finalStringerror;
OnError({
Key? key,
required [Link]
}) :super(key: key);

@override
Widget build(BuildContext context) {
returnCenter(
child:Column(
mainAxisAlignment: [Link],
children:<Widget>[
constIcon(
Icons.error_outline
color: [Link],
size:60,
),
Padding(
padding: const [Link](top: 16),
child:Text('Error:${error}'),
)
]
)
);
}
}
77
Interface
class Waiting extends StatelessWidget {
constWaiting({
Key? key,
}) :super(key: key);

@override
Widget build(BuildContext context) {
returnCenter(
child:Column(
mainAxisAlignment: [Link],
children:const<Widget>[
SizedBox(
width:60,
height:60,
child:CircularProgressIndicator(),
),
Padding(
padding: [Link](top: 16),
child:Text('Awaiting result...'),
)
]
)
);
}
}

78
Interface
class OnSuccess extends StatelessWidget {
finalDatadata;
OnSuccess({
Key? key,
required [Link]
}) :super(key: key);

@override
Widget build(BuildContext context) {
returnCenter(
child:Column(
mainAxisAlignment: [Link],
children: <Widget>[
constIcon(
Icons.check_circle_outline
color: [Link],
size:60,
),
Padding(
padding:[Link](top:16),
child:Text('Result:$
{[Link]!.[Link]}'},
)
]
),
);
}
} 79
FirebaseCloud
Firestore
Create a Firebase project

• Access theFirebase consoleand click on


Add a project.

• Enter a project name and click on


Continue.

81
Integration of Firebase with Android, iOS, and Web

Select the desired platform icon from the Firebase dashboard.

82
Web platform configuration

• Select the Web icon on the dashboard.

83
Web platform configuration

• Enter the application nickname and click on Register the application

84
Web platform configuration

• Add the Firebase SDK

85
Activate Cloud Firestore
• You can enable the Firestore database by selecting Firestore in the
left menu, then by clicking on Create a database.

86
Adding Firebase to Flutter

• firebase_core: required for Firebase initialization and the use of any other plugin
Firebase.
• cloud_firestore: required to interact with the Firestore database.

87
Initialization
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/[Link]';

Future<void> main() async {


[Link]();
[Link](
constFirebaseOptions(
apiKey:"AIzaSyB_Qlovx15Cx_-h5TPzaBog8oRW4e8ykd8",
authDomain:"[Link]",
projectId:"blog-930aa",
storageBucket:"[Link]",
messagingSenderId:"252280810021",
appId:"1:252280810021:web:e6668c21a58d92edd86dcc",
measurementId:"G-R7TG59DGRQ"
)
);
runApp(constMyApp());
}
88
Model
classArticle {
Article({
[Link]
required [Link],
required [Link],
[Link],
});

finalString?id;
finalDateTime?createdAt;
finalStringtitle;
finalStringbody;

[Link](QueryDocumentSnapshot query) =>Article(


id: [Link],
title: query["title"],
body: query["body"],
createdAt: ([Link]()asMap).containsKey("createdAt") ? query["createdAt"].toDate() :
null,
);

Map<String,dynamic> toJson() => {


"title":title,
"body":body,
"createdAt":[Link](),
};
} 89
Add a document
import 'package:cloud_firestore/cloud_firestore.dart';

final FirebaseFirestore firestore = [Link]

Article article = Article(


title:"codicem nondum per aetatem firmato",
body:"Circa Phalangio Baeticae consulari cecidit funesti
butchers.
);
[Link]('articles').add(
[Link]()
);

90
Display list of documents
import 'package:cloud_firestore/cloud_firestore.dart';

final FirebaseFirestore firestore = [Link]

FutureBuilder(
future: [Link]("articles")
.orderBy("createdAt", descending:true)
.get(),
builder: (context, snapshot) {
if([Link]){
returnOnError(message: [Link]());
}else if([Link]){
QuerySnapshot collection = [Link];
returnBuildListArticle(collection: collection);
}
return constCenter(
child:CircularProgressIndicator()
);
}
},
)
91
Show list of documents
import 'package:cloud_firestore/cloud_firestore.dart';

final FirebaseFirestore firestore = [Link]

StreamBuilder
stream:[Link]("articles")
.orderBy("createdAt",descending:true)
Snapshots (include metadata changes: true)
builder: (context, snapshot) {
if([Link]){
returnOnError(message: [Link]());
}else if([Link]){
QuerySnapshot collection = [Link]
QuerySnapshot;
returnBuildListArticle(collection: collection);
else{
return constCenter(
child:CircularProgressIndicator()
);
}
},
)
92
Show list of documents
class BuildListArticle extends StatelessWidget {
constBuildListArticle({
Key? key,
required [Link],
}) :super(key: key);

finalQuerySnapshot<Object?>collection;

@override
Widget build(BuildContext context) {
[Link](
itemCount:[Link],
itemBuilder: (context, index) {
Article article = [Link]([Link][index]);
returnItemCard(article: article);
},
);
}
}

93
Display list of documents
class ItemCard extends StatelessWidget {
constItemCard({
Key? key,
required [Link],
}) :super(key: key);
finalArticlearticle;
@override
Widget build(BuildContext context) {
returnPadding(
padding: const [Link](8.0),
child:Card(
elevation:8,
child:Column(
children: [
Align(
alignment: [Link],
child:Text([Link]!.toIso8601String()),
),
ListTile
title:Text([Link]),
subtitle:Text([Link]),
),
],
)
),
);
}
} 94
Display list of documents
class OnError extends StatelessWidget {
finalStringmessage;
constOnError({
Key? key,
[Link],
}) :super(key: key);

@override
Widget build(BuildContext context) {
returnCenter(
child:Text(message,
style:constTextStyle(color: [Link]),
),
);
}
}

95
MR
ECI
FOR YOUR VOTE
ATTENTION

You might also like