Flutter:如何调用本地 JSON 数据并动态添加到标签栏?
Posted
技术标签:
【中文标题】Flutter:如何调用本地 JSON 数据并动态添加到标签栏?【英文标题】:Flutter : How to call Local JSON Data and added to Tabbar dinamically? 【发布时间】:2022-01-21 06:39:36 【问题描述】:我希望通过使用 JSON 来缩短我的代码。请帮忙,如何将本地 JSON 生成到 Tabbar 中?以前我读过这个网站的帖子,但它调用 JSON API,而不是 LOCAL JSON。我还是不明白怎么称呼它
我想要这样的应用
我的 JSON 文件 (assets/product.json)
[
"id": 1,
"title": "NoteBook",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor.",
"image": "assets/img/notebook.jpg",
"price": "Rp. 13.000.000"
,
"id": 2,
"title": "Printer",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor.",
"image": "assets/img/printer.jpg",
"price": "Rp. 700.000"
,
"id": 3,
"title": "Mouse",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor.",
"image": "assets/img/standard-mouse.jpg",
"price": "Rp. 1.100.000"
,
"id": 4,
"title": "Keyboard",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor.",
"image": "assets/img/rgb-keyboard.jpg",
"price": "Rp. 2.100.000"
,
"id": 5,
"title": "Mouse Gaming",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor.",
"image": "assets/img/gaming-mouse.jpg",
"price": "Rp. 500.000"
,
"id": 6,
"title": "Proccessor",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor.",
"image": "assets/img/procie.jpg",
"price": "Rp. 6.000.000"
,
"id": 7,
"title": "Solid State Drive",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor.",
"image": "assets/img/ssd.jpg",
"price": "Rp. 2.100.000"
]
我的产品模型 (ProductModel.dart)
import 'dart:convert';
List<Product> ProductFromJson(String str) =>
List<Product>.from(json.decode(str).map((x) => Product.fromJson(x)));
class Product
Product(
this.id,
this.title,
this.image,
this.description,
this.price,
);
final int id;
final String title;
final String image;
final String description;
final String price;
factory Product.fromJson(Map<String, dynamic> json) => Product(
id: json["id"],
title: json["title"],
image: json["image"],
description: json["description"],
price: json["price"],
);
String getTitle()
return title;
String getImage()
return image;
String getDescription()
return description;
String getPrice()
return price;
我的主页(MainPage.dart)
import 'package:flutter/material.dart';
class MainPage extends StatefulWidget
const MainPage(Key key) : super(key: key);
@override
State<MainPage> createState() => _MainPageState();
class _MainPageState extends State<MainPage>
with SingleTickerProviderStateMixin
TabController myTabController;
List<Widget> myTabs = [];
List<Widget> myTabsContent = [];
@override
void initState()
super.initState();
myTabController = TabController(vsync: this, length: myTabs.length);
@override
Widget build(BuildContext context)
return Scaffold(
appBar: AppBar(
titleSpacing: 10,
title: Text("My Store"),
bottom: TabBar(
labelPadding: EdgeInsets.fromLTRB(20, 0, 20, 10),
isScrollable: true,
controller: myTabController,
tabs: myTabs.toList(),
),
),
body: TabBarView(
controller: myTabController,
children: myTabsContent.toList(),
),
);
【问题讨论】:
【参考方案1】:您可以尝试此方法从 json 加载产品并使用 FutureBuilder 加载内容并将其显示到您的标签:
Future<List<Product>> _getProducts() async
// Load json from file system
final dataString =
await rootBundle.loadString('assets/product.json');
// Decode to json
final List<dynamic> json = jsonDecode(dataString);
// Go through each post and convert json to Post object.
final products = <Product>[];
json.forEach((v)
products.add(Product.fromJson(v));
);
return products;
基于您的代码的示例(您需要更新代码以根据结果处理 myTabs 和 myTabsContent 的初始值):
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class MainPage extends StatefulWidget
const MainPage(Key? key) : super(key: key);
@override
State<MainPage> createState() => _MainPageState();
class _MainPageState extends State<MainPage>
with SingleTickerProviderStateMixin
late TabController myTabController;
List<Widget> myTabs = const [
Tab(icon: Icon(Icons.directions_car)),
Tab(icon: Icon(Icons.directions_transit)),
Tab(icon: Icon(Icons.directions_bike)),
];
List<Widget> myTabsContent = [];
Future<List<Product>> _getProducts() async
// Load json from file system
final dataString = await rootBundle.loadString('assets/product.json');
// Decode to json
final List<dynamic> json = jsonDecode(dataString);
// Go through each post and convert json to Post object.
final products = <Product>[];
json.forEach((v)
products.add(Product.fromJson(v));
);
return products;
@override
void initState()
super.initState();
myTabController = TabController(vsync: this, length: myTabs.length);
@override
Widget build(BuildContext context)
return FutureBuilder(
future: _getProducts(),
builder: (context, AsyncSnapshot<List<Product>> snapshot)
if (snapshot.connectionState == ConnectionState.done)
return Scaffold(
appBar: AppBar(
titleSpacing: 10,
title: const Text("My Store"),
bottom: TabBar(
isScrollable: true,
controller: myTabController,
tabs: myTabs,
),
),
body: TabBarView(controller: myTabController, children: [
_buildItems(snapshot.data!.first),
Icon(Icons.directions_transit),
Icon(Icons.directions_bike),
]),
);
else
return const Icon(Icons.directions_car);
);
Widget _buildItems(Product product)
return Column(
children: [
Text(product.title),
Text(product.price)
],
);
//
List<Product> ProductFromJson(String str) =>
List<Product>.from(json.decode(str).map((x) => Product.fromJson(x)));
class Product
Product(
required this.id,
required this.title,
required this.image,
required this.description,
required this.price,
);
final int id;
final String title;
final String image;
final String description;
final String price;
factory Product.fromJson(Map<String, dynamic> json) => Product(
id: json["id"],
title: json["title"],
image: json["image"],
description: json["description"],
price: json["price"],
);
String getTitle()
return title;
String getImage()
return image;
String getDescription()
return description;
String getPrice()
return price;
Here is result
【讨论】:
我收到错误消息_TypeError(类型'List这是我添加您的代码后的代码。但数据未显示:( Mr booykoquay
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class MainPage extends StatefulWidget
const MainPage(Key key) : super(key: key);
@override
State<MainPage> createState() => _MainPageState();
class _MainPageState extends State<MainPage>
with SingleTickerProviderStateMixin
TabController myTabController;
List<Widget> myTabs = [];
List<Widget> myTabsContent = [];
Future<List<Product>> _getProducts() async
// Load json from file system
final dataString = await rootBundle.loadString('assets/product.json');
// Decode to json
final List<dynamic> json = jsonDecode(dataString);
// Go through each post and convert json to Post object.
final products = <Product>[];
json.forEach((v)
products.add(Product.fromJson(v));
);
return products;
@override
void initState()
super.initState();
myTabController = TabController(vsync: this, length: myTabs.length);
@override
Widget build(BuildContext context)
return FutureBuilder(
future: _getProducts(),
builder: (context, _)
return Scaffold(
appBar: AppBar(
titleSpacing: 10,
title: const Text("My Store"),
bottom: TabBar(
isScrollable: true,
controller: myTabController,
tabs: myTabs.toList(),
),
),
body: TabBarView(
controller: myTabController,
children: myTabsContent.toList(),
),
);
);
//
List<Product> ProductFromJson(String str) =>
List<Product>.from(json.decode(str).map((x) => Product.fromJson(x)));
class Product
Product(
this.id,
this.title,
this.image,
this.description,
this.price,
);
final int id;
final String title;
final String image;
final String description;
final String price;
factory Product.fromJson(Map<String, dynamic> json) => Product(
id: json["id"],
title: json["title"],
image: json["image"],
description: json["description"],
price: json["price"],
);
String getTitle()
return title;
String getImage()
return image;
String getDescription()
return description;
String getPrice()
return price;
【讨论】:
【参考方案3】:问题已解决,这是我的代码
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class MainPage extends StatefulWidget
const MainPage(Key key) : super(key: key);
@override
State<MainPage> createState() => _MainPageState();
class _MainPageState extends State<MainPage>
with SingleTickerProviderStateMixin
Future<List<Product>> _getProducts() async
final dataString = await rootBundle.loadString('assets/product.json');
final List<dynamic> json = jsonDecode(dataString);
final products = <Product>[];
for (var v in json)
products.add(Product.fromJson(v));
return products;
@override
Widget build(BuildContext context)
return FutureBuilder<List<Product>>(
future: _getProducts(),
builder: (c, s)
if (s.hasData)
List<Tab> tabs = <Tab>[];
for (int i = 0; i < s.data.length; i++)
tabs.add(Tab(
child: Text(
s.data[i].title,
),
));
return DefaultTabController(
length: s.data.length,
child: Scaffold(
appBar: AppBar(
title: const Text("My Store"),
bottom: TabBar(
isScrollable: true,
tabs: tabs,
),
),
body: FutureBuilder<List<Product>>(
future: _getProducts(),
builder: (c, s)
if (s.hasData)
List<Widget> tabs = <Widget>[];
for (int i = 0; i < s.data.length; i++)
tabs.add(Tab(
child: SingleChildScrollView(
physics: const BouncingScrollPhysics(
parent: AlwaysScrollableScrollPhysics()),
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 20, vertical: 0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
const SizedBox(height: 30),
Text(
s.data[i].title,
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold),
),
const SizedBox(height: 30),
Image.asset(s.data[i].image),
const SizedBox(height: 30),
Text(s.data[i].title),
const SizedBox(height: 30),
Text(s.data[i].description),
],
),
),
),
));
return TabBarView(
children: tabs,
);
return Container();
,
),
),
);
return Scaffold(
body: Center(
child: Text(s.hasError ? s.error.toString() : "Loading...")),
);
,
);
// Product Model
List<Product> ProductFromJson(String str) =>
List<Product>.from(json.decode(str).map((x) => Product.fromJson(x)));
class Product
Product(
this.id,
this.title,
this.image,
this.description,
this.price,
);
final int id;
final String title;
final String image;
final String description;
final String price;
factory Product.fromJson(Map<String, dynamic> json) => Product(
id: json["id"],
title: json["title"],
image: json["image"],
description: json["description"],
price: json["price"],
);
String getTitle()
return title;
String getImage()
return image;
String getDescription()
return description;
String getPrice()
return price;
【讨论】:
以上是关于Flutter:如何调用本地 JSON 数据并动态添加到标签栏?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Flutter Mobile App 中加载和查询本地 json 数据