在 Flutter 中,我如何使用 API 和 GetX 在 JSON 中获取数据
Posted
技术标签:
【中文标题】在 Flutter 中,我如何使用 API 和 GetX 在 JSON 中获取数据【英文标题】:In Flutter how I can fetch data inside a JASON with API and GetX 【发布时间】:2021-06-17 04:11:19 【问题描述】:在 Flutter 中,我尝试过这种方式,但没有任何输出。我想从保存 JASON 数据的 URL 中获取数据,并根据名称、价格、图像等获取所有数据。但我无法使用以下方法。代码有什么问题。谁能帮我?谢谢。
这是我的 product_model.dart 文件
// To parse this JSON data, do
//
// final product = productFromJson(jsonString);
import 'dart:convert';
Product productFromJson(String str) => Product.fromJson(json.decode(str));
String productToJson(Product data) => json.encode(data.toJson());
class Product
Product(
this.code,
this.meta,
this.data,
);
int code;
Meta meta;
List<Datum> data;
factory Product.fromJson(Map<String, dynamic> json) => Product(
code: json["code"],
meta: Meta.fromJson(json["meta"]),
data: List<Datum>.from(json["data"].map((x) => Datum.fromJson(x))),
);
Map<String, dynamic> toJson() =>
"code": code,
"meta": meta.toJson(),
"data": List<dynamic>.from(data.map((x) => x.toJson())),
;
class Datum
Datum(
this.id,
this.name,
this.description,
this.image,
this.price,
this.discountAmount,
this.status,
this.categories,
);
int id;
String name;
String description;
String image;
String price;
String discountAmount;
bool status;
List<Category> categories;
factory Datum.fromJson(Map<String, dynamic> json) => Datum(
id: json["id"],
name: json["name"],
description: json["description"],
image: json["image"],
price: json["price"],
discountAmount: json["discount_amount"],
status: json["status"],
categories: List<Category>.from(json["categories"].map((x) => Category.fromJson(x))),
);
Map<String, dynamic> toJson() =>
"id": id,
"name": name,
"description": description,
"image": image,
"price": price,
"discount_amount": discountAmount,
"status": status,
"categories": List<dynamic>.from(categories.map((x) => x.toJson())),
;
class Category
Category(
this.id,
this.name,
);
int id;
String name;
factory Category.fromJson(Map<String, dynamic> json) => Category(
id: json["id"],
name: json["name"],
);
Map<String, dynamic> toJson() =>
"id": id,
"name": name,
;
class Meta
Meta(
this.pagination,
);
Pagination pagination;
factory Meta.fromJson(Map<String, dynamic> json) => Meta(
pagination: Pagination.fromJson(json["pagination"]),
);
Map<String, dynamic> toJson() =>
"pagination": pagination.toJson(),
;
class Pagination
Pagination(
this.total,
this.pages,
this.page,
this.limit,
);
int total;
int pages;
int page;
int limit;
factory Pagination.fromJson(Map<String, dynamic> json) => Pagination(
total: json["total"],
pages: json["pages"],
page: json["page"],
limit: json["limit"],
);
Map<String, dynamic> toJson() =>
"total": total,
"pages": pages,
"page": page,
"limit": limit,
;
这是我的 api_service.dart 文件
import 'package:http/http.dart' as http;
import 'package:mashmart/models/product_model.dart';
class ApiService
static var client = http.Client();
static Future<List<Product>> fetchProducts() async
var url = Uri.https(
'https://gorest.co.in', '/public-api/products');
var response = await client.get(url);
if (response.statusCode == 200)
var jasonString = response.body;
return productFromJson(jasonString);
else
print('Request failed with status: $response.statusCode.');
return null;
这是我的 product_controller.dart 文件
import 'package:get/state_manager.dart';
import 'package:mashmart/models/product_model.dart';
import 'package:mashmart/services/api_service.dart';
class ProductController extends GetxController
var isLoading = true.obs;
var productList = List<Product>().obs;
@override
void onInit()
fetchProducts();
super.onInit();
void fetchProducts() async
try
isLoading(true);
var products = await ApiService.fetchProducts();
if(products != null)
productList.value = products;
finally
isLoading(false);
这是我的 homepage.dart 文件
import 'package:flutter/material.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:get/get.dart';
import 'package:mashmart/controllers/product_controller.dart';
import 'package:mashmart/services/api_service.dart';
import 'package:mashmart/views/products/product_tile.dart';
class HomePage extends StatelessWidget
final GlobalKey<ScaffoldState> _key = GlobalKey<ScaffoldState>();
final ProductController productController = Get.put(ProductController());
@override
Widget build(BuildContext context)
return Scaffold(
key: _key,
drawer: Drawer(),
appBar: AppBar(
title: Text(
"Category",
style: TextStyle(color: Colors.black87),
),
centerTitle: true,
elevation: 0.0,
backgroundColor: Colors.grey[100],
leading: IconButton(
icon: Icon(Icons.menu_rounded),
color: Colors.black87,
onPressed: ()
print("Drawer Menu Clicked");
_key.currentState.openDrawer();
,
),
actions: <Widget>[
Stack(
children: [
IconButton(
icon: Icon(
Icons.shopping_cart,
size: 30,
color: Colors.black87,
),
onPressed: ()
print("Cart Clicked");
),
Positioned(
top: 20,
right: 4,
child: Container(
height: 22,
width: 22,
padding: EdgeInsets.all(4),
decoration: BoxDecoration(
shape: BoxShape.circle, color: Colors.deepPurple),
child: Center(
child: Text(
"0",
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
color: Colors.white),
),
),
),
),
],
),
Stack(
children: [
IconButton(
icon: Icon(
Icons.notifications_rounded,
size: 30,
color: Colors.black87,
),
onPressed: ()
print("Notifications Clicked");
),
Positioned(
top: 20,
right: 4,
child: Container(
height: 22,
width: 22,
padding: EdgeInsets.all(4),
decoration: BoxDecoration(
shape: BoxShape.circle, color: Colors.deepPurple),
child: Center(
child: Text(
"0",
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
color: Colors.white),
),
),
),
),
],
),
],
),
body: Column(
children: [
Padding(
padding: const EdgeInsets.all(16),
child: Row(
children: [
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextFormField(
decoration: InputDecoration(
hintText: "Search for markets or products",
prefixIcon: Icon(Icons.search_rounded),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
)),
onTap: ()
print("Search Box Tapped");
,
),
],
),
),
],
),
),
Padding(
padding: const EdgeInsets.all(16),
child: Row(
children: [
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
"Products",
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Colors.black87),
),
Row(
children: [
IconButton(
icon: Icon(
Icons.list_rounded,
color: Colors.black87,
),
onPressed: ()
print("List Clicked");
),
IconButton(
icon: Icon(
Icons.grid_view,
color: Colors.black,
),
onPressed: ()
print("Grid Clicked");
),
],
)
],
),
],
),
),
],
),
),
Expanded(
child: Obx(()
if (productController.isLoading.value)
return Center(child: CircularProgressIndicator());
else
print("Total Products = " +
productController.productList.length.toString());
return ListView.builder(
itemCount: productController.productList.length,
itemBuilder: (context, index)
return Column(
children: [
Row(
children: [
Container(
width: 150,
height: 100,
margin: EdgeInsets.fromLTRB(16, 8, 8, 8),
child: ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Image.network(
productController.productList[index].image,
width: 150,
height: 100,
fit: BoxFit.fill,
color: Colors.red,
colorBlendMode: BlendMode.color,
),
),
),
Flexible(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
productController.,
style: TextStyle(fontSize: 18),
),
Text(
productController.productList[index].name,
style: TextStyle(fontSize: 18),
),
],
))
],
),
Container(
color: Colors.black12,
height: 2,
)
],
);
,
);
),
)
],
),
);
【问题讨论】:
【参考方案1】:首先,您可以验证该网站上的模型是否正确创建: https://app.quicktype.io/
如果一切正常,问题可能出在这一行:
return Product.productFromJson (jasonString);
在它返回的数据类型中,如果你注意到它不是一个数组,它是一个单一的对象,在这种情况下,函数应该是:
Future <Product> fetchProducts () async ...
【讨论】:
谢谢。如何获取产品详细信息并获取它们?【参考方案2】: @override
Widget build(BuildContext context)
return Scaffold(
drawer: Drawer(),
appBar: buildAppBar(),
body: Column(
children: [
buildTextInputSearch(),
buildProductsToolBar(),
Obx(() => buildResultList()),
],
),
);
/* ---------------------------------------------------------------------------- */
Widget buildResultList()
GoRestService goRest = Get.find();
return Expanded(
child: goRest.isLoading.value!
? Center(child: CircularProgressIndicator())
: ListView.builder(
itemCount: goRest.numOfProducts,
itemBuilder: (context, index) => Column(
children: [
结果:
完整代码可以在here找到。
【讨论】:
以上是关于在 Flutter 中,我如何使用 API 和 GetX 在 JSON 中获取数据的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Flutter 中使用 Razorpay 订单 API?
如何在 Flutter 中使用 Provider 正确获取 API