将 Json 数据解析为现有的 Flutter 小部件
Posted
技术标签:
【中文标题】将 Json 数据解析为现有的 Flutter 小部件【英文标题】:Parse Json Data into Existing Flutter Widget 【发布时间】:2020-11-16 17:22:18 【问题描述】:你好,我现在正在学习颤振,我正在尝试获取 json 数据并将其显示在轮播小部件上,下面是完整的代码,以便您了解发生了什么
import 'package:flutter/material.dart';
import 'package:mares/components/drawer.dart';
import 'package:carousel_pro/carousel_pro.dart';
import 'package:mares/components/homecards.dart';
import 'package:mares/pages/contactus.dart';
import 'package:mares/pages/profile.dart';
import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart' as http;
void main() => runApp(MyApp());
class MyApp extends StatelessWidget
// This widget is the root of your application.
@override
Widget build(BuildContext context)
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Elaph Training',
theme: ThemeData(fontFamily: 'Roboto'),
home: MyHomePage(),
);
class MyHomePage extends StatefulWidget
@override
_MyHomePageState createState() => _MyHomePageState();
class _MyHomePageState extends State<MyHomePage>
Future<List> getSlides() async
final response = await http.get("http://igh-eg.com/mares/json/slides.php");
return json.decode(response.body);
@override
Widget build(BuildContext context)
Widget imagecarousel = new Container(
height: 200.0,
child: new Carousel(
boxFit: BoxFit.cover,
images: [
AssetImage('assets/slide1.jpg'),
AssetImage('assets/slide2.jpg'),
AssetImage('assets/slide3.jpg'),
],
autoplay: true,
animationCurve: Curves.fastOutSlowIn,
animationDuration: Duration(milliseconds: 2000),
dotSize: 5.0,
dotColor: const Color.fromRGBO(234, 91, 12, 1),
),
);
return Scaffold(
appBar: new AppBar(
backgroundColor: const Color.fromRGBO(32, 102, 174, 1),
title: Text('Elaph Training Center'),
actions: <Widget>[
new IconButton(icon: Icon(Icons.phone_in_talk, color: Colors.white,), onPressed: ()Navigator.of(context).push(new MaterialPageRoute(builder: (context) => new ContactUsPage()));),//search button
new IconButton(icon: Icon(Icons.supervised_user_circle, color: Colors.white,), onPressed: ()Navigator.of(context).push(new MaterialPageRoute(builder: (context) => new Profilepage()));),//cart button
],
),
//--the end of the app bar--//
//---start of the drawer---//
drawer: NavDrawer(),
body: new ListView(
children: <Widget>[
new FutureBuilder<List>(
future: getSlides(),
builder: (context, snapshot)
if (snapshot.hasError) print(snapshot.error);
return snapshot.hasData
? new ItemList(
list: snapshot.data,
)
: new Center(
child: new CircularProgressIndicator(),
);
,
),
imagecarousel,
SizedBox(height: 10.0,),
HomeCards(),
],
),
);
class ItemList extends StatelessWidget
final List list;
ItemList(this.list);
@override
Widget build(BuildContext context)
return new ListView.builder(
itemCount: list == null ? 0 : list.length,
itemBuilder: (context, i)
return new Container(
padding: const EdgeInsets.all(10.0),
child: new Card(
child: new ListTile(
title: new Text(list[i]['name']),
leading: new Image.network("http://igh-eg.com/mares/img/$list[i]['photo']"),
subtitle: new Text("Description : $list[i]['desc']"),
),
),
);
,
);
目前数据是代码在上面定义的 listitem 类中运行良好,但是我希望数据显示在如下所示的轮播部分上
Widget imagecarousel = new Container(
height: 200.0,
child: new Carousel(
boxFit: BoxFit.cover,
images: [
AssetImage('assets/slide1.jpg'),
AssetImage('assets/slide2.jpg'),
AssetImage('assets/slide3.jpg'),
],
autoplay: true,
animationCurve: Curves.fastOutSlowIn,
animationDuration: Duration(milliseconds: 2000),
dotSize: 5.0,
dotColor: const Color.fromRGBO(234, 91, 12, 1),
),
);
有什么帮助吗?我在网上搜索了很多,我看不到我错过了什么
【问题讨论】:
【参考方案1】:我已经用carousel_slider: ^2.2.1
& cached_network_image: ^2.1.0+1
包实现了类似的代码。
你可以试试下面的代码:
class _HomeScreenState extends State<HomeScreen>
Future<List<Product>> carouselProducts;
...
// method to fecth data from URL
Future<List<Product>> getSlides() async
return await apiController.carouselDataFetch();
@override
void initState()
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_)
carouselProducts = getSlides();
);
构建方法中的小部件:
FutureBuilder<List<Product>>(
future: carouselProducts,
builder: (BuildContext cont, AsyncSnapshot snapshot)
if (snapshot.connectionState != ConnectionState.done)
return Center(child: CircularProgressIndicator());
if (snapshot.connectionState == ConnectionState.none)
return Center(
child: Text("Turn-On Mobile Data / WiFi Please!",));
if (snapshot.hasError)
return Center(
child: Text("Something went wrong!",));
return CarouselSlider.builder(
options: CarouselOptions(
height: 250,
autoPlay: true,
enableInfiniteScroll: false,
enlargeCenterPage: true,
scrollDirection: Axis.horizontal,
scrollPhysics: const BouncingScrollPhysics(),
enlargeStrategy: CenterPageEnlargeStrategy.height,
autoPlayCurve: Curves.fastLinearToSlowEaseIn,
),
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index)
Product prod = snapshot.data[index];
return CachedNetworkImage(
imageUrl: prod.productImage,
fit: BoxFit.fill,
useOldImageOnUrlChange: true,
fadeInCurve: Curves.linearToEaseOut,
placeholder: (context, url) => Center(
child: CircularProgressIndicator()),
errorWidget: (context, url, error) =>
Icon(Icons.error),
);
,
);
,
)
输出:
仅供参考: 根据您的 API 响应数据更改此示例代码。
【讨论】:
【参考方案2】:谢谢大家,但我发现问题出在我使用的小部件版本上,所以我只是按照以下步骤操作
第 1 步:我将版本 (carousel_pro: ^0.0.13) 添加到 pubspec.yaml
第 2 步:创建以下 dart 文件
import 'package:carousel_pro/carousel_pro.dart';
import 'package:flutter/material.dart';
Widget CarouselSlider(items) => SizedBox(
height: 200,
child: Carousel(
boxFit: BoxFit.cover,
images: items,
autoplay: true,
animationCurve: Curves.fastOutSlowIn,
animationDuration: Duration(milliseconds: 1500),
),
);
然后在main.dart里面初始化状态时使用http,get获取数据,如下
class _MyHomePageState extends State<MyHomePage>
var items = [];
@override
void initState()
// TODO: implement initState
super.initState();
//get json data function//
getSlides();
Future<List> getSlides() async
final response = await http.get("http://igh-eg.com/mares/json/slides.php");
var result = json.decode(response.body);
result['data'].forEach((data)
setState(()
items.add(NetworkImage("http://igh-eg.com/mares/img/$data['photo']"));
);
);
print(json.decode(response.body));
return json.decode(response.body);
@override
Widget build(BuildContext context)
return Scaffold(
appBar: new AppBar(
backgroundColor: const Color.fromRGBO(32, 102, 174, 1),
title: Text('Elaph Training Center'),
actions: <Widget>[
new IconButton(icon: Icon(Icons.phone_in_talk, color: Colors.white,), onPressed: ()Navigator.of(context).push(new MaterialPageRoute(builder: (context) => new ContactUsPage()));),//search button
new IconButton(icon: Icon(Icons.supervised_user_circle, color: Colors.white,), onPressed: ()Navigator.of(context).push(new MaterialPageRoute(builder: (context) => new Profilepage()));),//cart button
],
),
//--the end of the app bar--//
//---start of the drawer---//
drawer: NavDrawer(),
body: new ListView(
children: <Widget>[
CarouselSlider(items),
SizedBox(height: 10.0,),
HomeCards(),
],
),
);
它像图表一样工作,如果您正在处理大量数据和图像,更好的方法是使用 pub.dev 网站上的 networkcachedimage 小部件
感谢大家,特别感谢@Sanket Vekariya 的帮助
【讨论】:
以上是关于将 Json 数据解析为现有的 Flutter 小部件的主要内容,如果未能解决你的问题,请参考以下文章
不可解析的父 POM,尽管 relativePath 设置为现有的父 pom.xml
使用Flutter + V8/JsCore开发小程序引擎(一)