未来"<dynamic>不是类型为"流<列表"的子类型<dynamic>>



我正在尝试使用StreamBuilder从API获取数据,请帮助解决此错误

Future'不是类型'Stream> '的子类型。

基本上我们正在获取数据和显示数据与ListView的帮助。builder和StreamBuilder:

Search_product.dart

import 'dart:async';
import 'package:beauty/user.dart';
import 'package:flutter/material.dart';
import 'package:beauty/backend.dart';
class SearchProduct extends StatefulWidget {
@override
_SearchProductState createState() => _SearchProductState();
}
class _SearchProductState extends State<SearchProduct> {
List<Welcome> _welcome;
Backend backend = new Backend();
bool waiting = true;
Stream _stream;
@override
void initState() {
// TODO: implement initState
super.initState();
Backend.getData().then((welcome) {
setState(() {
_welcome = welcome;
waiting = false;
});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xFFEBEAEF),
appBar: AppBar(
title: Row(children: [
SizedBox(
width: 70.0,
),
Text(
'Search Product',
style: TextStyle(
color: Colors.black,
),
),
SizedBox(
width: 70.0,
),
Flexible(
child: CircleAvatar(
child: Image.asset('assets/her.png'),
),
),
]),
leading: IconButton(
icon: Icon(
Icons.arrow_back,
color: Colors.black,
),
onPressed: () {},
),
backgroundColor: Color(0xFFEBEAEF),
),
body: Column(children: [
Container(
color: Colors.white70,
child: TextField(
decoration: InputDecoration(
prefixIcon: Icon(
Icons.search,
color: Colors.grey,
),
hintText: 'Search  for product',
contentPadding:
EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(12.0)),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.white70, width: 1.0),
borderRadius: BorderRadius.all(Radius.circular(12.0)),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.white70, width: 2.0),
borderRadius: BorderRadius.all(Radius.circular(12.0)),
),
),
style: TextStyle(color: Colors.black),
),
),
Container(
child: waiting
? SizedBox(
width: 50,
height: 50,
child: CircularProgressIndicator(),
)
: Expanded(
child: StreamBuilder(
stream: Backend.getData(),
builder: (BuildContext context,
AsyncSnapshot<List<dynamic>> snapshot) {
return ListView.builder(
padding: EdgeInsets.all(8),
itemCount: null == _welcome ? 0 : _welcome.length,
itemBuilder: (BuildContext context, int index) {
Welcome welcome = _welcome[index];
return Card(
child: Column(
children: <Widget>[
ListTile(
leading: CircleAvatar(
radius: 30,
backgroundImage: NetworkImage(snapshot
.data[index].welcome.image),
),
title: Text(
snapshot.data[index].welcome.title),
subtitle: Text(snapshot
.data[index].welcome.description),
trailing: Text(snapshot
.data[index].welcome.price
.toString()),
)
],
),
);
});
}),
),
),
]));
}
}

Backend.dart

import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:beauty/user.dart';
class Backend {
static getData() async {
try {
var url = Uri.parse('https://fakestoreapi.com/products');
var response = await http.get(url);
if (response.statusCode == 200) {
return welcomeFromJson(response.body);
} else {
List error_message = ['error'];
return error_message;
}
} catch (e) {
print(e);
}
}
}

user.dart

import 'dart:convert';

List<Welcome> welcomeFromJson(String str) =>
List<Welcome>.from(json.decode(str).map((x) => Welcome.fromJson(x)));

String welcomeToJson(List<Welcome> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

class Welcome {
Welcome({
this.id,
this.title,
this.price,
this.description,
this.category,
this.image,
this.rating,
});

int id;
String title;
double price;
String description;
Category category;
String image;
Rating rating;

factory Welcome.fromJson(Map<String, dynamic> json) => Welcome(
id: json["id"],
title: json["title"],
price: json["price"].toDouble(),
description: json["description"],
category: categoryValues.map[json["category"]],
image: json["image"],
rating: Rating.fromJson(json["rating"]),
);

Map<String, dynamic> toJson() => {
"id": id,
"title": title,
"price": price,
"description": description,
"category": categoryValues.reverse[category],
"image": image,
"rating": rating.toJson(),
};
}

enum Category { MEN_S_CLOTHING, JEWELERY, ELECTRONICS, WOMEN_S_CLOTHING }

final categoryValues = EnumValues({
"electronics": Category.ELECTRONICS,
"jewelery": Category.JEWELERY,
"men's clothing": Category.MEN_S_CLOTHING,
"women's clothing": Category.WOMEN_S_CLOTHING
});

class Rating {
Rating({
this.rate,
this.count,
});

double rate;
dynamic count;

factory Rating.fromJson(Map<String, dynamic> json) => Rating(
rate: json["rate"].toDouble(),
count: json["count"],
);

Map<String, dynamic> toJson() => {
"rate": rate,
"count": count,
};
}

class EnumValues<T> {
Map<String, T> map;
Map<T, String> reverseMap;

EnumValues(this.map);

Map<T, String> get reverse {
if (reverseMap == null) {
reverseMap = map.map((k, v) => new MapEntry(v, k));
}
return reverseMap;
}
}

Backend.getData的响应类型为Future,不是.

代替

StreamBuilder(
stream: Backend.getData(),
builder: (BuildContext context, AsyncSnapshot<List<dynamic>> snapshot) {

FutureBuilder(
future: Backend.getData(),
builder: (BuildContext context, AsyncSnapshot<List<dynamic>> snapshot) {
//show visual loading
if(!snapshot.hasData) return Center(child: CircularProgressIndicator());

由于类型不匹配而发生错误。

<表类> 当前 预期 tbody><<tr>预期数据List<dynamic>List<Welcome>?streamFuture<dynamic>Stream<List<Welcome>?>snapshotAsyncSnapshot<List<dynamic>>AsyncSnapshot<List<Welcome>?>

最新更新