list functionnal test

This commit is contained in:
Valentin CZERYBA 2024-06-23 17:23:26 +02:00
parent 672fb17904
commit 4df3b2a286
3 changed files with 116 additions and 7 deletions

View File

@ -0,0 +1,95 @@
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
import 'classes/post.dart';
// app starting point
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: const ListItemMenu(),
debugShowCheckedModeBanner: false,
);
}
}
// homepage class
class ListItemMenu extends StatefulWidget {
const ListItemMenu({super.key});
@override
State<ListItemMenu> createState() => _MyHomePageState();
}
// homepage state
class _MyHomePageState extends State<ListItemMenu> {
// variable to call and store future list of posts
Future<List<Post>> postsFuture = getPosts();
// function to fetch data from api and return future list of posts
static Future<List<Post>> getPosts() async {
var url = Uri.parse("https://jsonplaceholder.typicode.com/albums/1/photos");
final response =
await http.get(url, headers: {"Content-Type": "application/json"});
final List body = json.decode(response.body);
return body.map((e) => Post.fromJson(e)).toList();
}
// build function
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
// FutureBuilder
child: FutureBuilder<List<Post>>(
future: postsFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
// until data is fetched, show loader
return const CircularProgressIndicator();
} else if (snapshot.hasData) {
// once data is fetched, display it on screen (call buildPosts())
final posts = snapshot.data!;
return buildPosts(posts);
} else {
// if no data, show simple Text
return const Text("No data available");
}
},
),
),
);
}
// function to display fetched data on screen
Widget buildPosts(List<Post> posts) {
// ListView Builder to show data in a list
return ListView.builder(
itemCount: posts.length,
itemBuilder: (context, index) {
final post = posts[index];
return Container(
color: Colors.grey.shade300,
margin: EdgeInsets.symmetric(vertical: 5, horizontal: 10),
padding: EdgeInsets.symmetric(vertical: 5, horizontal: 5),
height: 100,
width: double.maxFinite,
child: Row(
children: [
Expanded(flex: 1, child: Image.network(post.url!)),
SizedBox(width: 10),
Expanded(flex: 3, child: Text(post.title!)),
],
),
);
},
);
}
}

View File

@ -0,0 +1,17 @@
class Post {
int? albumId;
int? id;
String? title;
String? url;
String? thumbnailUrl;
Post({this.albumId, this.id, this.title, this.url, this.thumbnailUrl});
Post.fromJson(Map<String, dynamic> json) {
albumId = json['albumId'];
id = json['id'];
title = json['title'];
url = json['url'];
thumbnailUrl = json['thumbnailUrl'];
}
}

View File

@ -5,7 +5,8 @@ import 'package:http/http.dart' as http;
import 'dart:convert';
import 'dart:io';
import 'MyHomePage.dart';
//import 'MyHomePage.dart';
import 'ListItemMenu.dart';
import 'classes/alert.dart';
@ -74,9 +75,7 @@ class _LoginDemoState extends State<LoginDemo> with ShowErrorDialog {
}
}
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => MyHomePage(title: 'Flutter Demo')));
context, MaterialPageRoute(builder: (_) => ListItemMenu()));
} else {
var text = "";
switch (response.statusCode) {
@ -136,9 +135,7 @@ class _LoginDemoState extends State<LoginDemo> with ShowErrorDialog {
headers: {HttpHeaders.cookieHeader: 'access_token: ${access_token}'});
if (responseToken.statusCode == 200) {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => MyHomePage(title: 'Flutter Demo')));
context, MaterialPageRoute(builder: (_) => ListItemMenu()));
} else {
prefs.remove("access_token");
}