当我使用滚动控制器控制网格视图时遇到问题。我遇到了错误(“String”类型不是“index”的“int”类型的子类型)。但在使用滚动控制器之前它工作得很好。我不需要更改以消除此错误。我还在stackoverflow中检查了有关此的其他问题,但无法得到它。任何人都可以检查并告诉我这里可以更改什么以消除错误并显示数据,以及我的条件是否适合在每个滚动端加载 10 个数据。
import 'dart:convert';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:gridview_screoll/grid_content.dart';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
import 'constant.dart';
class ScrollableGrid extends StatefulWidget {
@override
_ScrollableGridState createState() => _ScrollableGridState();
}
class _ScrollableGridState extends State<ScrollableGrid> {
List data = [];
bool isLoading = false;
ScrollController _scrollController;
int pageCount = 1;
@override
void initState() {
// TODO: implement initState
super.initState();
this.fetchTopProducts();
addItemIntoLisT(pageCount);
_scrollController = new ScrollController(initialScrollOffset: 5.0)
..addListener(_scrollListener);
}
_scrollListener() {
if (_scrollController.offset >=
_scrollController.position.maxScrollExtent &&
!_scrollController.position.outOfRange) {
setState(() {
isLoading = true;
if (isLoading) {
pageCount = pageCount + 1;
addItemIntoLisT(pageCount);
}
});
}
}
void addItemIntoLisT(var pageCount) {
for (int i = (pageCount * 10) - 10; i < pageCount * 10; i++) {
fetchTopProducts();
isLoading = false;
}
}
@override
void dispose() {
_scrollController.dispose();
super.dispose();
}
fetchTopProducts() async {
setState(() {
isLoading = true;
});
var url = base_api + "api_frontend/top_products";
var response = await http.get(url);
print(response.body);
if (response.statusCode == 200) {
setState(() {
data.add(json.decode(response.body)['top_products']);
isLoading = false;
});
} else {
setState(() {
data = [];
isLoading = false;
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 0.1,
backgroundColor: Colors.indigo,
title: Text('GridControll'),
//backgroundColor: Color.fromRGBO(244, 246, 249, 1),
),
body: SingleChildScrollView(
child: Column(
children: [
Container(
height: MediaQuery.of(context).size.height * 88/100,
color: Color.fromRGBO(244, 246, 249, 1),
margin: const EdgeInsets.only(
left: 0.0, bottom: 2.0, right: 0.0, top: 0),
child: getBody2(),
),
],
),
),
);
}
Widget getBody2() {
if (isLoading || data.length == 0) {
return Center(
child: CircularProgressIndicator(
valueColor: new AlwaysStoppedAnimation<Color>(primary)));
}
return StaggeredGridView.countBuilder(
padding: const EdgeInsets.all(10.0),
controller: _scrollController,
shrinkWrap: true,
// physics: NeverScrollableScrollPhysics(),
crossAxisCount: 2,
itemCount: data.length - 1,
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
//builder: (context) => ProductDetails(item: data2[index]),
builder: (context) => productDetail(data[index]),
),
);
},
child: cardItem2(data[index]));
},
staggeredTileBuilder: (int index) => StaggeredTile.fit(1),
mainAxisSpacing: 10.0,
crossAxisSpacing: 10.0,
);
}
}
这是grid_content.dart:
import 'package:html_unescape/html_unescape.dart';
import 'package:flutter/material.dart';
Widget cardItem2(item) {
// var img = item['thumbnail'];
// var thumbnail = base_api+"uploads/product_thumbnails/"+img;
var productId = item['product_id'];
var thumbnail = item['thumbnail'];
var unescape = new HtmlUnescape();
var name = unescape.convert(item['name']);
var unit = item['unit'];
var discount = item['discount'];
var price = item['price'];
var discountPrice = item['discount_price'];
return discount != '0%' ? Card(
elevation: 6,
shadowColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(9.0)),
child: Stack(
fit: StackFit.loose,
alignment: Alignment.center,
children: [
Column(
children: <Widget>[
Stack(
children: [
ClipRRect(
borderRadius: BorderRadius.only(topRight: Radius.circular(9), topLeft: Radius.circular(9)),
child: FadeInImage.assetNetwork(
placeholder: 'assets/loading_animated.gif',
image: thumbnail,
height: 110,
width: double.infinity,
fit: BoxFit.cover,
),
),
],
),
Padding(
padding: const EdgeInsets.only(left:6.0, right: 6.0),
child: Row(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
name,
style: TextStyle(
fontSize: 16.0,
color: Colors.black87,
fontWeight: FontWeight.w100,
),
),
Text(
unit,
style: TextStyle(
fontSize: 12.0,
color: Colors.black45,
fontWeight: FontWeight.w100,
),
),
Row(
children: [
Expanded(
flex: 2,
child: Text(
discountPrice,
style: TextStyle(
fontSize: 16.0,
color: Colors.green,
fontWeight: FontWeight.w500,
),
),
),
Expanded(
flex: 2,
child: Text(
price,
style: TextStyle(
fontSize: 12.0,
color: Colors.black38,
fontWeight: FontWeight.w500,
decoration: TextDecoration.lineThrough,
),
),
),
ButtonTheme(
padding: EdgeInsets.symmetric(vertical: 4.0, horizontal: 6.0), //adds padding inside the button
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, //limits the touch area to the button area
minWidth: 0, //wraps child's width
height: 25,
child: FlatButton(
minWidth: 5,
height: 40,
color: Color.fromRGBO(100, 186, 2, 1),
onPressed: () {
},
child: Icon(Icons.shopping_cart, color: Colors.white,),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
side: BorderSide(color: Color.fromRGBO(100, 186, 2, 1),)),
),
),
],
),
],
),
),
),
],
),
),
],
),
],
),
) : Card(
elevation: 6,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(9.0)),
child: Stack(
fit: StackFit.loose,
alignment: Alignment.center,
children: [
Column(
children: <Widget>[
Stack(
children: [
ClipRRect(
borderRadius: BorderRadius.only(topRight: Radius.circular(9), topLeft: Radius.circular(9)),
child: FadeInImage.assetNetwork(
placeholder: 'assets/loading_animated.gif',
image: thumbnail,
height: 110,
width: double.infinity,
fit: BoxFit.cover,
),
),
],
),
Padding(
padding: const EdgeInsets.only(left:6.0, right: 6.0),
child: Row(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
name,
style: TextStyle(
fontSize: 16.0,
color: Colors.black87,
fontWeight: FontWeight.w100,
),
),
Text(
unit,
style: TextStyle(
fontSize: 12.0,
color: Colors.black45,
fontWeight: FontWeight.w100,
),
),
Row(
children: [
Expanded(
flex: 1,
child: Text(
price,
style: TextStyle(
fontSize: 15.0,
color: Colors.green,
fontWeight: FontWeight.w500,
),
),
),
ButtonTheme(
padding: EdgeInsets.symmetric(vertical: 4.0, horizontal: 6.0),
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
minWidth: 0, //wraps child's width
height: 25,
child: FlatButton(
minWidth: 10,
//height: 40,
color: Color.fromRGBO(100, 186, 2, 1),
onPressed: () {
},
child: Icon(Icons.shopping_cart, color: Colors.white,),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
side: BorderSide(color: Color.fromRGBO(100, 186, 2, 1),)),
),
),
],
),
],
),
),
),
],
),
),
],
),
],
),
);
}
productDetail(item) {
// var img = item['thumbnail'];
// var thumbnail = base_api+"uploads/product_thumbnails/"+img;
var productId = item['product_id'];
var thumbnail = item['thumbnail'];
var unescape = new HtmlUnescape();
var name = unescape.convert(item['name']);
var discount = item['discount'];
var price = item['price'];
var disPrice= item['discount_price'];
var unit = item['unit'];
return Scaffold(
appBar: AppBar(
elevation: 0.1,
iconTheme: IconThemeData(color: Colors.white),
backgroundColor: Colors.red,
title: Center(
child: Padding(
padding: const EdgeInsets.only(right: 50),
child: Text(
'Product Details',
style: TextStyle(color: Colors.white),
),
),
),
actions: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 15, right: 25.0),
child: GestureDetector(
child: Stack(
alignment: Alignment.topCenter,
children: <Widget>[
Icon(
Icons.favorite,
),
],
),
onTap: () {},
),
)
],
),
body: SingleChildScrollView(
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
child: FadeInImage.assetNetwork(
placeholder: 'assets/black_circle.gif',
image: thumbnail,
height: 210,
width: 360,
fit: BoxFit.cover,
),
),
),
Center(
child: Card(
color: Colors.white38,
child: Padding(
padding: const EdgeInsets.only(left: 12.0, right: 12, top: 4, bottom: 4),
child: Text(
unit,
style: TextStyle(
fontSize: 11,
color: Colors.black87,
),
),
),
),
),
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Center(
child: discount != '0%' ? Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
disPrice,
style: TextStyle(
fontSize: 22,
color: Colors.black87,
fontWeight: FontWeight.bold),
),
Padding(
padding: const EdgeInsets.only(left: 8.0),
child: Text(
price,
style: TextStyle(
fontSize: 18,
color: Colors.black54,
decoration: TextDecoration.lineThrough,
),
),
),
],
): Text(
price,
style: TextStyle(
fontSize: 22,
color: Colors.black87,
fontWeight: FontWeight.bold),
),
),
),
Padding(
padding: const EdgeInsets.only(top: 4.0),
child: Center(
child: Text(
name,
style: TextStyle(
fontSize: 18,
color: Colors.black54,
),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Divider(),
),
Container(
child: Center(
child: Text(
'Quantity',
style: TextStyle(color: Colors.black45, fontSize: 15),
),
),
),
Container(
child: Center(
child: Text(
'1',
style: TextStyle(
color: Colors.black,
fontSize: 22,
fontWeight: FontWeight.bold),
),
),
//child: Text(store.activeProduct.qty.toString()),
),
Padding(
padding: const EdgeInsets.only(
left: 100.0, right: 100.0, bottom: 10.0),
child: FlatButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
side: BorderSide(color: Color.fromRGBO(41, 193, 126, 1)),
),
color: Color.fromRGBO(41, 193, 126, 1),
padding: EdgeInsets.only(top: 8, bottom: 8),
child: Center(
child: Text(
'BUY NOW',
style: TextStyle(color: Colors.white, fontSize: 16),
),
),
onPressed: () {
}),
),
Padding(
padding: const EdgeInsets.only(
left: 100.0, right: 100.0, bottom: 10.0),
child: FlatButton(
padding: EdgeInsets.only(top: 8, bottom: 8),
child: Center(
child: Text(
'ADD TO CART',
style: TextStyle(color: Color.fromRGBO(41, 193, 126, 1), fontSize: 16),
),
),
onPressed: () {
}),
),
],
),
),
),
);
}
这是json文件:
{
"top_products": [
{
"product_id": "63",
"category_id": "59",
"name": "Ice Cream",
"price": "$9",
"discount_price": "$8.91",
"discount": "1%",
"unit": "3 kg",
"thumbnail": "http://192.168.0.105/uploads/product_thumbnails/72908baa78a2db38f678283a2e483903.jpg"
},
{
"product_id": "65",
"category_id": "47",
"name": "Malta",
"price": "$5",
"discount_price": "$4.5",
"discount": "10%",
"unit": "1 kg",
"thumbnail": "http://192.168.0.105/uploads/product_thumbnails/a63dcb5e4f883eb946585d287d25c397.jpg"
},
{},
{},
{},
...
],
"message": "Top hundred products",
"status": 200,
"validity": true
}
======== Exception caught by widgets library =======================================================
The following _TypeError was thrown building:
type 'String' is not a subtype of type 'int' of 'index'
When the exception was thrown, this was the stack:
#0 cardItem2 (package:gridview_screoll/grid_content.dart:7:23)
#1 _ScrollableGridState.getBody2.<anonymous closure> (package:gridview_screoll/scroll_grid.dart:130:20)
#2 SliverChildBuilderDelegate.build (package:flutter/src/widgets/sliver.dart:449:22)
#3 SliverVariableSizeBoxAdaptorElement._build.<anonymous closure> (package:flutter_staggered_grid_view/src/widgets/sliver.dart:144:38)
#4 _HashMap.putIfAbsent (dart:collection-patch/collection_patch.dart:140:29)
...
====================================================================================================