Flutter 使用颤振提供程序将数据传递到另一个屏幕
我试图使用Flutter 使用颤振提供程序将数据传递到另一个屏幕,flutter,mobile,flutter-dependencies,flutter-provider,Flutter,Mobile,Flutter Dependencies,Flutter Provider,我试图使用提供程序将数据传递到另一个屏幕,但似乎我总是传递相同的数据,除非我对列表进行排序,然后传递不同的数据(这意味着我可能通过对列表进行排序来切换索引,这就是它现在传递不同数据的原因)。简言之,我调用API,填充列表,为下一页设置提供程序,然后单击“列出上一屏幕中的信息”,但问题是除非对列表进行排序,否则我总是显示相同的项目。代码如下: 调用API并显示列表: var posts = <RideData>[]; var streamController = StreamCo
提供程序将数据传递到另一个屏幕,但似乎我总是传递相同的数据,除非我对列表进行排序,然后传递不同的数据(这意味着我可能通过对列表进行排序来切换索引,这就是它现在传递不同数据的原因)。简言之,我调用API,填充列表,为下一页设置提供程序,然后单击“列出上一屏幕中的信息”,但问题是除非对列表进行排序,否则我总是显示相同的项目。代码如下:
调用API并显示列表:
var posts = <RideData>[];
var streamController = StreamController<List<RideData>>();
@override
void initState() {
_getRideStreamList();
super.initState();
}
_getRideStreamList() async {
await Future.delayed(Duration(seconds: 3));
var _vehicleStreamData = await APICalls.instance.getRides();
var provider = Provider.of<RideStore>(context, listen: false);
posts = await _vehicleStreamData
.map<RideData>((e) => RideData.fromJson(e))
.toList();
streamController.add(posts);
provider.setRideList(posts, notify: false);
}
bool isSwitched = true;
void toggleSwitch(bool value) {
if (isSwitched == false) {
posts.sort((k1, k2) => k1.rideId.compareTo(k2.rideId));
} else {
posts.sort((k1, k2) => k2.rideId.compareTo(k1.rideId));
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: SafeArea(
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Column(
children: [
TextButton(
child: Text('sort ascending'),
onPressed: () {
setState(() {
toggleSwitch(isSwitched = !isSwitched);
});
}),
Container(
height: 1000,
child: StreamBuilder<List<RideData>>(
initialData: posts,
stream: streamController.stream,
builder: (context, snapshot) {
return ListView.builder(
shrinkWrap: true,
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return Column(
children: [
Row(
children: [
Padding(
padding: const EdgeInsets.only(left: 15.0),
child: Text(
'Ride #${snapshot.data[index].rideId}',
),
),
FlatButton(
textColor: Colors.blue[700],
minWidth: 0,
child: Text('View'),
onPressed: () {
// here is where I pass the data to the RideInfo screen
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => RideInfo(
rideId: snapshot
.data[index].rideId,
)));
},
),
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
'${snapshot.data[index].pickupTime}',
),
Text(
'${snapshot.data[index].jobArrived}',
),
],
),
],
);
},
);
}),
),
],
),
),
),
);
}
如何根据我在“行驶信息”屏幕中按下并传递的列表中的ID显示正确的信息,使其不会始终返回相同的数据?提前感谢您的帮助 有问题的代码位于RideInfo
:
ListView.builder(
shrinkWrap: true,
itemCount: 1,
itemBuilder: (context, index) {
RideData rides = rideStore.getRideByIndex(index);
索引始终是1
,因此您总是显示第一个RideData
。有多种选项可以修复它,例如将索引
,甚至将RideData
传递给RideInfo
构造函数:
class RideInfo extends StatefulWidget {
static const String id = 'ride_info_screen';
String rideId;
final int index;
RideInfo({@required this.rideId, @required this.index, Key key})
: super(key: key) {
以及:
我对代码有一些补充意见。首先,ListView
在RideInfo
中没有任何作用,所以将其删除
其次,不需要构造streamController
,也不需要在父窗体中使用StreamBuilder
。您的列表可在骑乘用品商店中找到。因此,您的父窗体可以有:
Widget build(BuildContext context) {
var data = Provider.of<RideStore>(context).rideList;
...
Container(
height: 1000,
child:
// StreamBuilder<List<RideData>>(
// initialData: posts,
// stream: streamController.stream,
// builder: (context, snapshot) {
// return
ListView.builder(
shrinkWrap: true,
itemCount: data.length,
在initState
中删除对\u getRideStreamList
的调用,并在调用\u getRideStreamList
的FutureBuilder
中包装列表视图
:
Container(
height: 1000,
child: FutureBuilder(
future: _getRideStreamList(),
builder: (ctx, snapshot) {
if (!snapshot.hasData) {
return Center(child: CircularProgressIndicator());
} else {
var data = snapshot.data;
return ListView.builder(
...
);
}
},
),
),
这将在等待数据时显示循环压缩机指示器
请注意,这是一个快速破解-您不希望每次小部件重建时都读取数据。因此,\u getRideStreamList
可以检查数据是否已被读取,并返回数据,而不是重新读取。首先,我要感谢您提供的详细答案,非常感谢!我通过了索引
在这种情况下,我不确定如何成功地将完整的骑乘数据
传递到骑乘信息
。其次,我使用了流生成器
,没有提供者
,所以在发布之前我没有机会重构它,但再次感谢您的提醒,我真的非常感谢。干杯别担心。您可以将RideData
传递给构造函数上的RideInfo
,就像任何值一样:RideData ride;RideInfo({@required RideData this.ride})
根据您的建议,我删除了不必要的代码,现在的问题是我需要刷新我的小部件,因为ListView.builder
在从API访问数据之前呈现小部件,我尝试使用FutureBuilder
并使用了“Provider”,因为我正在调用API,但我也遇到了同样的问题…请参见我对FutureBuilder
RideData rides = rideStore.getRideByIndex(widget.index);
Widget build(BuildContext context) {
var data = Provider.of<RideStore>(context).rideList;
...
Container(
height: 1000,
child:
// StreamBuilder<List<RideData>>(
// initialData: posts,
// stream: streamController.stream,
// builder: (context, snapshot) {
// return
ListView.builder(
shrinkWrap: true,
itemCount: data.length,
_getRideStreamList() async {
...
return posts;
}
Container(
height: 1000,
child: FutureBuilder(
future: _getRideStreamList(),
builder: (ctx, snapshot) {
if (!snapshot.hasData) {
return Center(child: CircularProgressIndicator());
} else {
var data = snapshot.data;
return ListView.builder(
...
);
}
},
),
),