簡體   English   中英

如何從 REST API 獲取數據並顯示在 Listview 上,Flutter

[英]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 上顯示它? 請我在這方面需要幫助。 只是為了澄清,因為我在這里學習這個。

有多種方法可以實現這一目標。

  1. 使用FutureBuilder
  2. 使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM