1
+ import 'dart:async' ;
2
+ import 'dart:convert' ;
3
+
4
+ import 'package:flutter/foundation.dart' ;
5
+ import 'package:flutter/material.dart' ;
6
+ import 'package:http/http.dart' as http;
7
+
8
+ Future <List <Photo >> fetchPhotos (http.Client client) async {
9
+ final response = await client
10
+ .get (Uri .parse ('https://jsonplaceholder.typicode.com/photos' ));
11
+
12
+ // Use the compute function to run parsePhotos in a separate isolate.
13
+ return compute (parsePhotos, response.body);
14
+ }
15
+
16
+ // A function that converts a response body into a List<Photo>.
17
+ List <Photo > parsePhotos (String responseBody) {
18
+ final parsed = jsonDecode (responseBody).cast <Map <String , dynamic >>();
19
+
20
+ return parsed.map <Photo >((json) => Photo .fromJson (json)).toList ();
21
+ }
22
+
23
+ class Photo {
24
+ final int albumId;
25
+ final int id;
26
+ final String title;
27
+ final String url;
28
+ final String thumbnailUrl;
29
+
30
+ Photo ({
31
+ required this .albumId,
32
+ required this .id,
33
+ required this .title,
34
+ required this .url,
35
+ required this .thumbnailUrl,
36
+ });
37
+
38
+ factory Photo .fromJson (Map <String , dynamic > json) {
39
+ return Photo (
40
+ albumId: json['albumId' ] as int ,
41
+ id: json['id' ] as int ,
42
+ title: json['title' ] as String ,
43
+ url: json['url' ] as String ,
44
+ thumbnailUrl: json['thumbnailUrl' ] as String ,
45
+ );
46
+ }
47
+ }
48
+
49
+ void main () => runApp (MyApp ());
50
+
51
+ class MyApp extends StatelessWidget {
52
+ @override
53
+ Widget build (BuildContext context) {
54
+ final appTitle = 'Isolate Demo' ;
55
+
56
+ return MaterialApp (
57
+ title: appTitle,
58
+ home: MyHomePage (title: appTitle),
59
+ );
60
+ }
61
+ }
62
+
63
+ class MyHomePage extends StatelessWidget {
64
+ final String title;
65
+
66
+ MyHomePage ({Key ? key, required this .title}) : super (key: key);
67
+
68
+ @override
69
+ Widget build (BuildContext context) {
70
+ return Scaffold (
71
+ appBar: AppBar (
72
+ title: Text (title),
73
+ ),
74
+ body: FutureBuilder <List <Photo >>(
75
+ future: fetchPhotos (http.Client ()),
76
+ builder: (context, snapshot) {
77
+ if (snapshot.hasError) print (snapshot.error);
78
+
79
+ return snapshot.hasData
80
+ ? PhotosList (photos: snapshot.data! )
81
+ : Center (child: CircularProgressIndicator ());
82
+ },
83
+ ),
84
+ );
85
+ }
86
+ }
87
+
88
+ class PhotosList extends StatelessWidget {
89
+ final List <Photo > photos;
90
+
91
+ PhotosList ({Key ? key, required this .photos}) : super (key: key);
92
+
93
+ @override
94
+ Widget build (BuildContext context) {
95
+ return GridView .builder (
96
+ gridDelegate: SliverGridDelegateWithFixedCrossAxisCount (
97
+ crossAxisCount: 2 ,
98
+ ),
99
+ itemCount: photos.length,
100
+ itemBuilder: (context, index) {
101
+ return Image .network (photos[index].thumbnailUrl);
102
+ },
103
+ );
104
+ }
105
+ }
0 commit comments