[英]use Flutter bloc to fetch data from Api in Listview element
[英]How to fetch data from REST API and display on Listview, Flutter
我對使用 REST API 獲取數據並在 Flutter 的列表視圖中顯示相當陌生。 從那以后我一直在做這樣的事情,但我一直迷路。 因此我需要幫助。
我的代碼就是這樣
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
class TransactionDetails {
final String avatar;
final String name;
final String date;
final String amount;
TransactionDetails({required this.avatar, required this.name, required this.date, required this.amount});
factory TransactionDetails.fromJson(Map<String, dynamic> json) {
return TransactionDetails(
avatar: json['avatar'],
name: json['name'],
date: json['date'],
amount: json['amount']);
}
}
class BaseScreen extends StatelessWidget {
const BaseScreen({Key? key}) : super(key: key);
Future<TransactionDetails> fetchTransaction() async {
final response = await http
.get('https://brotherlike-navies.000webhostapp.com/people/people.php');
if (response.statusCode == 200) {
return TransactionDetails.fromJson(json.decode(response.body));
} else {
throw Exception('Request Failed.');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: double.infinity,
height: 150,
child: ListView(
scrollDirection: Axis.horizontal,
children: [
Container(
margin: const EdgeInsets.all(15),
width: 319,
height: 100,
color: Colors.green,
alignment: Alignment.center,
child: const Text(
'\$5200.00',
style: TextStyle(
fontSize: 15,
color: Colors.white,
fontWeight: FontWeight.bold),
),
),
Container(
margin: const EdgeInsets.all(15),
width: 319,
height: 100,
color: Colors.green,
alignment: Alignment.center,
child: const Text(
'\$1200.00',
style: TextStyle(
fontSize: 15,
color: Colors.white,
fontWeight: FontWeight.bold),
),
),
SizedBox(height: 24),
],
),
),
Padding(
padding: EdgeInsets.all(15),
child: Text(
"Recent Transactions",
style: TextStyle(
fontSize: 14, fontWeight: FontWeight.bold, color: Colors.green),
),
),
ListView() //Display the data here from the REST API
],
)));
}
}
如何在 Listview 上顯示它? 請我在這方面需要幫助。 只是為了澄清,因為我在這里學習這個。
有多種方法可以實現這一目標。
FutureBuilder
StatefulWidget
& setState
目前,您正在使用StatelessWidget
(BaseScreen),所以我們只使用 go 和FutureBuilder
。
在點擊您給出的 url 時: https://brotherlike-navies.000webhostapp.com/people/people.php
它給出以下響應:
[{"avatar":"https:\/\/static.vecteezy.com\/system\/resources\/thumbnails\/002\/002\/403\/small\/man-with-beard-avatar-character-isolated-icon-free-vector.jpg","name":"Kayo Johnson","date":"09\/29\/2022","amount":"5000.00"},{"avatar":"https:\/\/static.vecteezy.com\/system\/resources\/thumbnails\/002\/002\/403\/small\/man-with-beard-avatar-character-isolated-icon-free-vector.jpg","name":"Kuta Joy","date":"09\/29\/2022","amount":"5000.00"},{"avatar":"https:\/\/static.vecteezy.com\/system\/resources\/thumbnails\/001\/993\/889\/small\/beautiful-latin-woman-avatar-character-icon-free-vector.jpg","name":"Timmi Phillips","date":"09\/28\/2022","amount":"3500.00"}]
它返回交易詳細信息對象的列表。 因此,您應該在 model TransactionDetail
中添加另一個方法,該方法將返回一個TransactionDetails
列表,如下所示:
class TransactionDetails {
final String avatar;
final String name;
final String date;
final String amount;
TransactionDetails(
{required this.avatar,
required this.name,
required this.date,
required this.amount});
factory TransactionDetails.fromJson(Map<String, dynamic> json) {
return TransactionDetails(
avatar: json['avatar'],
name: json['name'],
date: json['date'],
amount: json['amount']);
}
static List<TransactionDetails> fromJsonList(dynamic jsonList) {
final transactionDetailsList = <TransactionDetails>[];
if (jsonList == null) return transactionDetailsList;
if (jsonList is List<dynamic>) {
for (final json in jsonList) {
transactionDetailsList.add(
TransactionDetails.fromJson(json),
);
}
}
return transactionDetailsList;
}
}
更新您的 fetchTransaction 方法,如下所示:
Future<List<TransactionDetails>> fetchTransaction() async {
final response = await http
.get('https://brotherlike-navies.000webhostapp.com/people/people.php');
if (response.statusCode == 200) {
return TransactionDetails.fromJsonList(json.decode(response.body));
} else {
throw Exception('Request Failed.');
}
}
只需用FutureBuilder
小部件包裝您的ListView
小部件,如下所示:
FutureBuilder(
future: fetchTransaction(),
builder: (context, AsyncSnapshot<List<TransactionDetails>> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.data == null) {
return const Center(child: Text('Something went wrong'));
}
return ListView.builder(
itemCount: snapshot.data?.length ?? 0,
itemBuilder: (context, index) {
return ListTile(
title: Text(snapshot.data![index].name),
subtitle: Text(snapshot.data![index].amount),
);
});
}
return const CircularProgressIndicator();
},
),
試試下面的代碼:
您的TransactionDetails
詳情 Class
class TransactionDetails {
String? avatar;
String? name;
String? date;
String? amount;
TransactionDetails({
this.avatar,
this.name,
this.date,
this.amount,
});
TransactionDetails.fromJson(Map<String, dynamic> json) {
avatar = json['avatar'];
name = json['name'];
date = json['date'];
amount = json['amount'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['avatar'] = avatar;
data['name'] = name;
data['date'] = date;
data['amount'] = amount;
return data;
}
}
API 致電:
Future<List<TransactionDetails>> fetchAlbum() async {
final response = await http.get(Uri.parse(
'https://brotherlike-navies.000webhostapp.com/people/people.php'));
if (response.statusCode == 200) {
final List result = json.decode(response.body);
return result.map((e) => TransactionDetails.fromJson(e)).toList();
} else {
throw Exception('Failed to load data');
}
}
您的小部件:
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: double.infinity,
height: 150,
child: ListView(
scrollDirection: Axis.horizontal,
children: [
Container(
margin: const EdgeInsets.all(15),
width: 319,
height: 100,
color: Colors.green,
alignment: Alignment.center,
child: const Text(
'\$5200.00',
style: TextStyle(
fontSize: 15,
color: Colors.white,
fontWeight: FontWeight.bold),
),
),
Container(
margin: const EdgeInsets.all(15),
width: 319,
height: 100,
color: Colors.green,
alignment: Alignment.center,
child: const Text(
'\$1200.00',
style: TextStyle(
fontSize: 15,
color: Colors.white,
fontWeight: FontWeight.bold),
),
),
const SizedBox(height: 24),
],
),
),
const Padding(
padding: EdgeInsets.all(15),
child: Text(
"Recent Transactions",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold,
color: Colors.green),
),
),
Center(
child: FutureBuilder<List<TransactionDetails>>(
future: fetchAlbum(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
shrinkWrap: true,
itemCount: snapshot.data!.length,
itemBuilder: (context, index) {
return ListTile(
leading: CircleAvatar(
child: Image.network(
snapshot.data![index].avatar.toString()),
),
title: Text(snapshot.data![index].name.toString()),
trailing:
Text(snapshot.data![index].amount.toString()),
subtitle: Text(snapshot.data![index].date.toString()),
);
},
);
} else if (snapshot.hasError) {
return Text('${snapshot.error}');
}
return const CircularProgressIndicator();
},
),
),
],
),
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.