flutter 应用程序主页不显示数据

问题描述 投票:0回答:1

我尝试从 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');
    }
  }
}

我尝试了大部分展示产品的方式

flutter rest dart woocommerce woocommerce-rest-api
1个回答
0
投票

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.
              );
            }


 }

你想要这样的东西。 您可能想要编辑一些内容(我现在不在编辑器上)。

© www.soinside.com 2019 - 2024. All rights reserved.