我尝试从 Woocommerce API 获取产品数据并尝试在 flutter 的主页上显示此数据,但无法在首页上显示数据。我得到了 response.body 成功并在终端中打印,但我不知道为什么它没有显示在主屏幕上。有人可以帮我解决这个问题吗?
我提到的 Woocommerce 产品作为壁纸。
下面是用于获取数据的wallpaper.dart文件:
import 'package:flutter/material.dart';
import 'dart:async';
import '../model/wallpaper_model.dart';
import './home.dart';
import '../helper_services/helperservices.dart';
class WallpaperWidget extends StatefulWidget {
const WallpaperWidget({Key? key}) : super(key: key);
@override
State<WallpaperWidget> createState() => _WallpaperWidgetState();
}
class _WallpaperWidgetState extends State<WallpaperWidget> {
List<Products>? wallpapers;
var isLoaded = false;
@override
void initState() {
super.initState();
getData(); // Call getData to fetch wallpapers when the widget is initialized
}
getData() async {
wallpapers = await HelperService().getWallpapers();
if (wallpapers != null) {
setState(() {
isLoaded = true;
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Visibility(
visible: isLoaded,
child: ListView.builder(
itemCount: wallpapers?.length,
itemBuilder: (context, index) {
final wallpaper = wallpapers?[index];
return ListTile(
title: Text(wallpaper?.name ?? ''),
// Display other properties of the wallpaper as needed.
);
}
),
replacement: Center(
child: CircularProgressIndicator(),
),
),
);
}
}
下面是API调用的helperservice.dart:
import 'dart:convert';
import 'package:http/http.dart' as http;
import '../model/wallpaper_model.dart'; // Import the Products class from your product_model.dart file
class HelperService {
final String consumerKey = ''; // Replace with your actual consumer key
final String consumerSecret = ''; // Replace with your actual consumer secret
Future<List<Products>> getWallpapers() async {
final String url = 'https://my_site.in/wp-json/wc/v3/products';
// Encode consumer key and secret to base64
final String credentials = base64Encode(
utf8.encode('$consumerKey:$consumerSecret'),
);
try {
final response = await http.get(
Uri.parse(url), // Removed the per_page query parameter
headers: {
'Authorization': 'Basic $credentials',
},
);
if (response.statusCode == 200) {
// If the request is successful, parse the response
List<Products> products = productsFromJson(response.body);
return products;
} else {
throw Exception('Failed to load products');
}
} catch (e) {
print('Error: $e');
throw Exception('Error: $e');
}
}
}
我尝试了大部分展示产品的方式
GetData
是一个异步函数。这意味着执行需要时间,并且结果不能立即可用(简而言之)。
因此,当执行构建函数时,您还没有该数据。
即使将函数放在 initState 函数中,执行顺序也是:initState() -> build() -> "when have time getData()"
(再次强调,为了更简单)。
这是因为 flutter 是单线程的。
为了在不重新加载数据的情况下显示数据,只需使用 FutureBuilder()
,它会在加载您提供的数据时构建一个小部件。
class _WallpaperWidgetState extends State<WallpaperWidget> {
List<Products>? wallpapers;
var isLoaded = false;
late Future<dynamic> _future; //The type should be the type you receive from getData()
@override
void initState() {
super.initState();
_future = getData();
}
getData() async {
wallpapers = await HelperService().getWallpapers();
if (wallpapers != null) {
setState(() {
isLoaded = true;
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Visibility(
visible: isLoaded,
child : FutureBuilder<dynamic>( //edit type here too
future: _future, //the future that is loading from getData() function
builder: (context, snapshot) {
if (snapshot.hasError) {
children = <Widget>[
const Icon(
Icons.error_outline,
color: Colors.red,
size: 60,
),
Padding(
padding: const EdgeInsets.only(top: 16),
child: Text('Error: ${snapshot.error}'),
),
];
} else if (snapshot.connectionState == ConnectionState.waiting){
children = const <Widget>[
SizedBox(
width: 60,
height: 60,
child: CircularProgressIndicator(),
),
Padding(
padding: EdgeInsets.only(top: 16),
child: Text('Awaiting result...'),
),
];
}
return ListView.builder(
itemCount: snapshot?.length,
itemBuilder: (context, index) {
final wallpaper = snapshot?[index];
return ListTile(
title: Text(snapshot?.name ?? ''),
// Display other properties of the wallpaper as needed.
);
}
}
你想要这样的东西。 您可能想要编辑一些内容(我现在不在编辑器上)。