i'm trying to implement pull_to_refresh . I have two stateless widget that i will use . First is _ProductCategoryDetailPageState
here is the code
@override
Widget build(BuildContext context) {
return Material(
child: Scaffold(
appBar: AppBar(
title: Text(widget.categoryName),
),
body: Container(
height: MediaQuery.of(context).size.height,
child: Column(
children: <Widget>[
Divider(
height: 20.0,
),
Flexible(
child:StreamBuilder<List<Products>>(
stream: _productController.stream,
builder: (context, snapshot) {
if (snapshot.hasError) {
return errMess(context, "Failed to fetch data");
} else {
if (snapshot.hasData) {
if (snapshot.data.length > 0) {
return ProductList(category: snapshot.data);
} else {
return errMess(context,
"There is no available product in this category");
}
} else {
return errMess(context,
"There is no available product in this category");
}
}
},
)),
Divider(
height: 25.0,
),
],
),
)));
}
loadProduct(String categoryId, int limit, int offset) async {
List<Products> products = await fetchProducts(http.Client(), categoryId, limit, offset);
_productController.sink.add(products);
}
static List<Products> parseProducts(String responseBody) {
final parsed = json.decode(responseBody).cast<Map<String, dynamic>>();
return parsed.map<Products>((json) => Products.fromJson(json)).toList();
}
Future<List<Products>> fetchProducts(http.Client client, String categoryId, int limit, int offset) async {
final response = await http.post(Configuration.url +
"api/getProducts/" +
categoryId +
"/" +
limit.toString() +
"/" +
offset.toString());
if (response.statusCode < 200 || response.statusCode > 300) {
throw new Exception('Failed to fetch data');
} else {
return compute(parseProducts, response.body);
}
}
and here is my second stateless widget
class _ProductListState extends State<ProductList> {
int limit = 0;
int offset = 4;
RefreshController _refreshController2 =
RefreshController(initialRefresh: false);
@override
Widget build(BuildContext context) {
return SmartRefresher(
child: new GridView.builder(
itemCount: widget.category.length,
gridDelegate:
new SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
itemBuilder: (BuildContext context, int index) {
return new GestureDetector(
onTap: () {
print("Product detail");
},
child: Card(
semanticContainer: true,
clipBehavior: Clip.antiAliasWithSaveLayer,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: Image.network(
Configuration.url +
"assets/app_assets/" +
widget.category[index].productImage,
width: 250,
height: 250,
filterQuality: FilterQuality.low,
),
),
SizedBox(
height: 25,
),
Text(
widget.category[index].productName,
style: TextStyle(fontSize: 15.0),
),
SizedBox(
height: 25,
),
],
),
),
);
},
),
controller: _refreshController2,
enablePullUp: true,
header: MaterialClassicHeader(),
onRefresh: () {
_onRefresh(_refreshController2, widget.category,
widget.category[0].categoryId);
},
onLoading: () {
_onLoading(_refreshController2, widget.category,
widget.category[0].categoryId);
},
);
}
void _onLoading(RefreshController controller, List<Products> data,String categoryId) async {
await Future.delayed(Duration(milliseconds: 2000));
setState(() {
limit = limit + offset;
offset = 6;
});
_ProductCategoryDetailPageState().loadProduct(categoryId, limit, offset);
controller.loadComplete();
}
void _onRefresh(RefreshController controller, List<Products> data,
String categoryId) async {
await Future.delayed(Duration(milliseconds: 1000));
controller.refreshCompleted();
}
}
when i pull the grid there is no error , but the data is not change. After i check on this part
Flexible(
child:StreamBuilder<List<Products>>(
stream: _productController.stream,
builder: (context, snapshot) {
print("run")
if (snapshot.hasError) {
return errMess(context, "Failed to fetch data");
} else {
if (snapshot.hasData) {
if (snapshot.data.length > 0) {
return ProductList(category: snapshot.data);
} else {
return errMess(context,
"There is no available product in this category");
}
} else {
return errMess(context,
"There is no available product in this category");
}
}
},
)),
As you can see i adding print("run")
, it just only showing once.
my full script https://gist.github.com/bobykurniawan11/04f2584c6de97f1d9324bfe3b24f669f